chart
This commit is contained in:
		
							parent
							
								
									fcbee92929
								
							
						
					
					
						commit
						7461521a90
					
				| @ -227,8 +227,8 @@ | |||||||
|               <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"> | ||||||
|                   <option value="">Select Field</option> |                   <option value="">Select Field</option> | ||||||
|                   <!-- Use columnData for base API filters when drilldown is not enabled, drilldownColumnData when it is --> |                   <!-- Base API filters should always use columnData, not drilldownColumnData --> | ||||||
|                   <option *ngFor="let column of getAvailableFields(gadgetsEditdata.baseFilters, i, gadgetsEditdata.drilldownEnabled ? drilldownColumnData : columnData)" [value]="column">{{column}}</option> |                   <option *ngFor="let column of getAvailableFields(gadgetsEditdata.baseFilters, i, columnData)" [value]="column">{{column}}</option> | ||||||
|                 </select> |                 </select> | ||||||
|               </div> |               </div> | ||||||
|                |                | ||||||
| @ -324,17 +324,17 @@ | |||||||
|           <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 Filter Button --> |           <!-- Add Base Drilldown 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)="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 Filter Fields List --> |           <!-- Base Drilldown Filter Fields List --> | ||||||
|           <div *ngFor="let filter of gadgetsEditdata.baseFilters; 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;"> | ||||||
|               <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)="removeDrilldownFilter(i)"> | ||||||
|                 <clr-icon shape="trash"></clr-icon> |                 <clr-icon shape="trash"></clr-icon> | ||||||
|               </button> |               </button> | ||||||
|             </div> |             </div> | ||||||
| @ -343,7 +343,7 @@ | |||||||
|               <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"> | ||||||
|                   <option value="">Select Field</option> |                   <option value="">Select Field</option> | ||||||
|                   <option *ngFor="let column of getAvailableFields(gadgetsEditdata.baseFilters, i, drilldownColumnData)" [value]="column">{{column}}</option> |                   <option *ngFor="let column of getAvailableFields(gadgetsEditdata.drilldownFilters, i, drilldownColumnData)" [value]="column">{{column}}</option> | ||||||
|                 </select> |                 </select> | ||||||
|               </div> |               </div> | ||||||
|                |                | ||||||
| @ -353,7 +353,7 @@ | |||||||
|               </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)="removeDrilldownFilter(i)"> | ||||||
|                   <clr-icon shape="trash"></clr-icon> |                   <clr-icon shape="trash"></clr-icon> | ||||||
|                 </button> |                 </button> | ||||||
|               </div> |               </div> | ||||||
|  | |||||||
| @ -142,7 +142,8 @@ export class EditnewdashComponent implements OnInit { | |||||||
|     drilldownXAxis: '', |     drilldownXAxis: '', | ||||||
|     drilldownYAxis: '', |     drilldownYAxis: '', | ||||||
|     drilldownParameter: '', // Add drilldown parameter property
 |     drilldownParameter: '', // Add drilldown parameter property
 | ||||||
|     baseFilters: [] as any[], // Add base filters
 |     baseFilters: [] as any[], // Add base filters for API
 | ||||||
|  |     drilldownFilters: [] as any[], // Add separate drilldown filters
 | ||||||
|     // Multi-layer drilldown configurations
 |     // Multi-layer drilldown configurations
 | ||||||
|     drilldownLayers: [] as any[], |     drilldownLayers: [] as any[], | ||||||
|   }; |   }; | ||||||
| @ -530,6 +531,11 @@ export class EditnewdashComponent implements OnInit { | |||||||
|       this.gadgetsEditdata['baseFilters'] = [];  |       this.gadgetsEditdata['baseFilters'] = [];  | ||||||
|     } |     } | ||||||
|      |      | ||||||
|  |     // Initialize drilldown filters if not present
 | ||||||
|  |     if (item['drilldownFilters'] === undefined) {  | ||||||
|  |       this.gadgetsEditdata['drilldownFilters'] = [];  | ||||||
|  |     } | ||||||
|  |      | ||||||
|     // Initialize drilldown layers if not present
 |     // Initialize drilldown layers if not present
 | ||||||
|     if (item['drilldownLayers'] === undefined) {  |     if (item['drilldownLayers'] === undefined) {  | ||||||
|       this.gadgetsEditdata['drilldownLayers'] = [];  |       this.gadgetsEditdata['drilldownLayers'] = [];  | ||||||
| @ -550,6 +556,11 @@ export class EditnewdashComponent implements OnInit { | |||||||
|     // Reset drilldown column data
 |     // Reset drilldown column data
 | ||||||
|     this.drilldownColumnData = []; |     this.drilldownColumnData = []; | ||||||
|      |      | ||||||
|  |     // If drilldown is enabled and we have a drilldown API URL, fetch the drilldown column data
 | ||||||
|  |     if (this.gadgetsEditdata.drilldownEnabled && this.gadgetsEditdata.drilldownApiUrl) { | ||||||
|  |       this.refreshBaseDrilldownColumns(); | ||||||
|  |     } | ||||||
|  |      | ||||||
|     if (item.datastore !== undefined || '' || null) { |     if (item.datastore !== undefined || '' || null) { | ||||||
|       const datastore = item.datastore; |       const datastore = item.datastore; | ||||||
|       this.getTables(datastore); |       this.getTables(datastore); | ||||||
| @ -649,6 +660,7 @@ export class EditnewdashComponent implements OnInit { | |||||||
|         xyz.drilldownYAxis = this.gadgetsEditdata.drilldownYAxis; |         xyz.drilldownYAxis = this.gadgetsEditdata.drilldownYAxis; | ||||||
|         xyz.drilldownParameter = this.gadgetsEditdata.drilldownParameter; |         xyz.drilldownParameter = this.gadgetsEditdata.drilldownParameter; | ||||||
|         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.drilldownLayers = this.gadgetsEditdata.drilldownLayers; |         xyz.drilldownLayers = this.gadgetsEditdata.drilldownLayers; | ||||||
|          |          | ||||||
|         console.log(xyz); |         console.log(xyz); | ||||||
| @ -693,6 +705,7 @@ export class EditnewdashComponent implements OnInit { | |||||||
|       drilldownYAxis: item['drilldownYAxis'], |       drilldownYAxis: item['drilldownYAxis'], | ||||||
|       drilldownParameter: item['drilldownParameter'], // Add drilldown parameter
 |       drilldownParameter: item['drilldownParameter'], // Add drilldown parameter
 | ||||||
|       baseFilters: item['baseFilters'] || [], // Add base filters
 |       baseFilters: item['baseFilters'] || [], // Add base filters
 | ||||||
|  |       drilldownFilters: item['drilldownFilters'] || [], // Add drilldown filters
 | ||||||
|       // Multi-layer drilldown configurations
 |       // Multi-layer drilldown configurations
 | ||||||
|       drilldownLayers: item['drilldownLayers'] || [] |       drilldownLayers: item['drilldownLayers'] || [] | ||||||
|     }; |     }; | ||||||
| @ -740,6 +753,7 @@ export class EditnewdashComponent implements OnInit { | |||||||
|         updatedItem.drilldownYAxis = this.gadgetsEditdata.drilldownYAxis; |         updatedItem.drilldownYAxis = this.gadgetsEditdata.drilldownYAxis; | ||||||
|         updatedItem.drilldownParameter = this.gadgetsEditdata.drilldownParameter; |         updatedItem.drilldownParameter = this.gadgetsEditdata.drilldownParameter; | ||||||
|         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.drilldownLayers = this.gadgetsEditdata.drilldownLayers; |         updatedItem.drilldownLayers = this.gadgetsEditdata.drilldownLayers; | ||||||
|          |          | ||||||
|         console.log('Updated item:', updatedItem); |         console.log('Updated item:', updatedItem); | ||||||
| @ -973,6 +987,20 @@ export class EditnewdashComponent implements OnInit { | |||||||
|     this.gadgetsEditdata.baseFilters.splice(index, 1); |     this.gadgetsEditdata.baseFilters.splice(index, 1); | ||||||
|   } |   } | ||||||
|    |    | ||||||
|  |   // Add method to add a drilldown filter
 | ||||||
|  |   addDrilldownFilter() { | ||||||
|  |     const newFilter = { | ||||||
|  |       field: '', | ||||||
|  |       value: '' | ||||||
|  |     }; | ||||||
|  |     this.gadgetsEditdata.drilldownFilters.push(newFilter); | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   // Add method to remove a drilldown filter
 | ||||||
|  |   removeDrilldownFilter(index: number) { | ||||||
|  |     this.gadgetsEditdata.drilldownFilters.splice(index, 1); | ||||||
|  |   } | ||||||
|  |    | ||||||
|   // Add method to add a layer filter
 |   // Add method to add a layer filter
 | ||||||
|   addLayerFilter(layerIndex: number) { |   addLayerFilter(layerIndex: number) { | ||||||
|     const newFilter = { |     const newFilter = { | ||||||
|  | |||||||
| @ -30,6 +30,7 @@ export class BarChartComponent implements OnInit, OnChanges, OnDestroy { | |||||||
|   @Input() drilldownYAxis: string; |   @Input() drilldownYAxis: string; | ||||||
|   @Input() drilldownParameter: string; // Add drilldown parameter input
 |   @Input() drilldownParameter: string; // Add drilldown parameter input
 | ||||||
|   @Input() baseFilters: any[] = []; // Add base filters input
 |   @Input() baseFilters: any[] = []; // Add base filters input
 | ||||||
|  |   @Input() drilldownFilters: any[] = []; // Add drilldown filters input
 | ||||||
|   // Multi-layer drilldown configuration inputs
 |   // Multi-layer drilldown configuration inputs
 | ||||||
|   @Input() drilldownLayers: any[] = []; // Array of drilldown layer configurations
 |   @Input() drilldownLayers: any[] = []; // Array of drilldown layer configurations
 | ||||||
| 
 | 
 | ||||||
| @ -72,6 +73,7 @@ export class BarChartComponent implements OnInit, OnChanges, OnDestroy { | |||||||
|     const tableChanged = changes.table && !changes.table.firstChange; |     const tableChanged = changes.table && !changes.table.firstChange; | ||||||
|     const connectionChanged = changes.connection && !changes.connection.firstChange; |     const connectionChanged = changes.connection && !changes.connection.firstChange; | ||||||
|     const baseFiltersChanged = changes.baseFilters && !changes.baseFilters.firstChange; |     const baseFiltersChanged = changes.baseFilters && !changes.baseFilters.firstChange; | ||||||
|  |     const drilldownFiltersChanged = changes.drilldownFilters && !changes.drilldownFilters.firstChange; | ||||||
|     // Drilldown configuration changes
 |     // Drilldown configuration changes
 | ||||||
|     const drilldownEnabledChanged = changes.drilldownEnabled && !changes.drilldownEnabled.firstChange; |     const drilldownEnabledChanged = changes.drilldownEnabled && !changes.drilldownEnabled.firstChange; | ||||||
|     const drilldownApiUrlChanged = changes.drilldownApiUrl && !changes.drilldownApiUrl.firstChange; |     const drilldownApiUrlChanged = changes.drilldownApiUrl && !changes.drilldownApiUrl.firstChange; | ||||||
| @ -80,7 +82,7 @@ export class BarChartComponent implements OnInit, OnChanges, OnDestroy { | |||||||
|     const drilldownLayersChanged = changes.drilldownLayers && !changes.drilldownLayers.firstChange; |     const drilldownLayersChanged = changes.drilldownLayers && !changes.drilldownLayers.firstChange; | ||||||
|      |      | ||||||
|     // Only fetch data if the actual chart configuration changed and we're not already fetching
 |     // Only fetch data if the actual chart configuration changed and we're not already fetching
 | ||||||
|     if (!this.isFetchingData && (xAxisChanged || yAxisChanged || tableChanged || connectionChanged || baseFiltersChanged || |     if (!this.isFetchingData && (xAxisChanged || yAxisChanged || tableChanged || connectionChanged || baseFiltersChanged || drilldownFiltersChanged || | ||||||
|         drilldownEnabledChanged || drilldownApiUrlChanged || drilldownXAxisChanged || drilldownYAxisChanged || |         drilldownEnabledChanged || drilldownApiUrlChanged || drilldownXAxisChanged || drilldownYAxisChanged || | ||||||
|         drilldownLayersChanged)) { |         drilldownLayersChanged)) { | ||||||
|       console.log('Chart configuration changed, fetching new data'); |       console.log('Chart configuration changed, fetching new data'); | ||||||
| @ -296,10 +298,31 @@ export class BarChartComponent implements OnInit, OnChanges, OnDestroy { | |||||||
|         filterParams = JSON.stringify(filterObj); |         filterParams = JSON.stringify(filterObj); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|  |     console.log('Drilldown layer filter parameters:', filterParams); | ||||||
|      |      | ||||||
|     // Fetch data from the dashboard service with parameter field and value
 |     // Convert drilldownFilters to filter parameters for drilldown level
 | ||||||
|     // Backend handles filtering, we just pass the parameter field and value
 |     let drilldownFilterParams = ''; | ||||||
|     const subscription = this.dashboardService.getChartData(actualApiUrl, 'bar', drilldownConfig.xAxis, drilldownConfig.yAxis, this.connection, parameterField, parameterValue, filterParams).subscribe( |     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); | ||||||
|  |      | ||||||
|  |     // For drilldown level, we pass the parameter value from the drilldown stack and drilldown filters
 | ||||||
|  |     const subscription = this.dashboardService.getChartData( | ||||||
|  |       drilldownConfig.apiUrl, 'bar',  | ||||||
|  |       this.drilldownXAxis, this.drilldownYAxis,  | ||||||
|  |       this.connection,  | ||||||
|  |       parameterField, parameterValue, | ||||||
|  |       drilldownFilterParams | ||||||
|  |     ).subscribe( | ||||||
|       (data: any) => { |       (data: any) => { | ||||||
|         console.log('Received drilldown data:', data); |         console.log('Received drilldown data:', data); | ||||||
|         if (data === null) { |         if (data === null) { | ||||||
|  | |||||||
| @ -30,6 +30,7 @@ export class BubbleChartComponent implements OnInit, OnChanges { | |||||||
|   @Input() drilldownYAxis: string; |   @Input() drilldownYAxis: string; | ||||||
|   @Input() drilldownParameter: string; // Add drilldown parameter input
 |   @Input() drilldownParameter: string; // Add drilldown parameter input
 | ||||||
|   @Input() baseFilters: any[] = []; // Add base filters input
 |   @Input() baseFilters: any[] = []; // Add base filters input
 | ||||||
|  |   @Input() drilldownFilters: any[] = []; // Add drilldown filters input
 | ||||||
|   // Multi-layer drilldown configuration inputs
 |   // Multi-layer drilldown configuration inputs
 | ||||||
|   @Input() drilldownLayers: any[] = []; // Array of drilldown layer configurations
 |   @Input() drilldownLayers: any[] = []; // Array of drilldown layer configurations
 | ||||||
| 
 | 
 | ||||||
| @ -110,6 +111,7 @@ export class BubbleChartComponent implements OnInit, OnChanges { | |||||||
|     const tableChanged = changes.table && !changes.table.firstChange; |     const tableChanged = changes.table && !changes.table.firstChange; | ||||||
|     const connectionChanged = changes.connection && !changes.connection.firstChange; |     const connectionChanged = changes.connection && !changes.connection.firstChange; | ||||||
|     const baseFiltersChanged = changes.baseFilters && !changes.baseFilters.firstChange; |     const baseFiltersChanged = changes.baseFilters && !changes.baseFilters.firstChange; | ||||||
|  |     const drilldownFiltersChanged = changes.drilldownFilters && !changes.drilldownFilters.firstChange; | ||||||
|     // Drilldown configuration changes
 |     // Drilldown configuration changes
 | ||||||
|     const drilldownEnabledChanged = changes.drilldownEnabled && !changes.drilldownEnabled.firstChange; |     const drilldownEnabledChanged = changes.drilldownEnabled && !changes.drilldownEnabled.firstChange; | ||||||
|     const drilldownApiUrlChanged = changes.drilldownApiUrl && !changes.drilldownApiUrl.firstChange; |     const drilldownApiUrlChanged = changes.drilldownApiUrl && !changes.drilldownApiUrl.firstChange; | ||||||
| @ -118,7 +120,7 @@ export class BubbleChartComponent implements OnInit, OnChanges { | |||||||
|     const drilldownLayersChanged = changes.drilldownLayers && !changes.drilldownLayers.firstChange; |     const drilldownLayersChanged = changes.drilldownLayers && !changes.drilldownLayers.firstChange; | ||||||
|      |      | ||||||
|     // Only fetch data if the actual chart configuration changed and we're not already fetching
 |     // Only fetch data if the actual chart configuration changed and we're not already fetching
 | ||||||
|     if (!this.isFetchingData && (xAxisChanged || yAxisChanged || tableChanged || connectionChanged || baseFiltersChanged || |     if (!this.isFetchingData && (xAxisChanged || yAxisChanged || tableChanged || connectionChanged || baseFiltersChanged || drilldownFiltersChanged || | ||||||
|         drilldownEnabledChanged || drilldownApiUrlChanged || drilldownXAxisChanged || drilldownYAxisChanged || |         drilldownEnabledChanged || drilldownApiUrlChanged || drilldownXAxisChanged || drilldownYAxisChanged || | ||||||
|         drilldownLayersChanged)) { |         drilldownLayersChanged)) { | ||||||
|       console.log('Chart configuration changed, fetching new data'); |       console.log('Chart configuration changed, fetching new data'); | ||||||
| @ -305,13 +307,32 @@ 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, filterParams).subscribe( |     this.dashboardService.getChartData(actualApiUrl, 'bubble', drilldownConfig.xAxis, drilldownConfig.yAxis, this.connection, parameterField, parameterValue, finalFilterParams).subscribe( | ||||||
|       (data: any) => { |       (data: any) => { | ||||||
|         console.log('Received drilldown data:', data); |         console.log('Received drilldown data:', data); | ||||||
|         if (data === null) { |         if (data === null) { | ||||||
|  | |||||||
| @ -29,6 +29,7 @@ export class DoughnutChartComponent implements OnInit, OnChanges, AfterViewCheck | |||||||
|   @Input() drilldownYAxis: string; |   @Input() drilldownYAxis: string; | ||||||
|   @Input() drilldownParameter: string; // Add drilldown parameter input
 |   @Input() drilldownParameter: string; // Add drilldown parameter input
 | ||||||
|   @Input() baseFilters: any[] = []; // Add base filters input
 |   @Input() baseFilters: any[] = []; // Add base filters input
 | ||||||
|  |   @Input() drilldownFilters: any[] = []; // Add drilldown filters input
 | ||||||
|   // Multi-layer drilldown configuration inputs
 |   // Multi-layer drilldown configuration inputs
 | ||||||
|   @Input() drilldownLayers: any[] = []; // Array of drilldown layer configurations
 |   @Input() drilldownLayers: any[] = []; // Array of drilldown layer configurations
 | ||||||
| 
 | 
 | ||||||
| @ -153,6 +154,7 @@ export class DoughnutChartComponent implements OnInit, OnChanges, AfterViewCheck | |||||||
|     const tableChanged = changes.table && !changes.table.firstChange; |     const tableChanged = changes.table && !changes.table.firstChange; | ||||||
|     const connectionChanged = changes.connection && !changes.connection.firstChange; |     const connectionChanged = changes.connection && !changes.connection.firstChange; | ||||||
|     const baseFiltersChanged = changes.baseFilters && !changes.baseFilters.firstChange; |     const baseFiltersChanged = changes.baseFilters && !changes.baseFilters.firstChange; | ||||||
|  |     const drilldownFiltersChanged = changes.drilldownFilters && !changes.drilldownFilters.firstChange; | ||||||
|     // Drilldown configuration changes
 |     // Drilldown configuration changes
 | ||||||
|     const drilldownEnabledChanged = changes.drilldownEnabled && !changes.drilldownEnabled.firstChange; |     const drilldownEnabledChanged = changes.drilldownEnabled && !changes.drilldownEnabled.firstChange; | ||||||
|     const drilldownApiUrlChanged = changes.drilldownApiUrl && !changes.drilldownApiUrl.firstChange; |     const drilldownApiUrlChanged = changes.drilldownApiUrl && !changes.drilldownApiUrl.firstChange; | ||||||
| @ -161,7 +163,7 @@ export class DoughnutChartComponent implements OnInit, OnChanges, AfterViewCheck | |||||||
|     const drilldownLayersChanged = changes.drilldownLayers && !changes.drilldownLayers.firstChange; |     const drilldownLayersChanged = changes.drilldownLayers && !changes.drilldownLayers.firstChange; | ||||||
|      |      | ||||||
|     // Only fetch data if the actual chart configuration changed and we're not already fetching
 |     // Only fetch data if the actual chart configuration changed and we're not already fetching
 | ||||||
|     if (!this.isFetchingData && (xAxisChanged || yAxisChanged || tableChanged || connectionChanged || baseFiltersChanged || |     if (!this.isFetchingData && (xAxisChanged || yAxisChanged || tableChanged || connectionChanged || baseFiltersChanged || drilldownFiltersChanged || | ||||||
|         drilldownEnabledChanged || drilldownApiUrlChanged || drilldownXAxisChanged || drilldownYAxisChanged || |         drilldownEnabledChanged || drilldownApiUrlChanged || drilldownXAxisChanged || drilldownYAxisChanged || | ||||||
|         drilldownLayersChanged)) { |         drilldownLayersChanged)) { | ||||||
|       console.log('Chart configuration changed, fetching new data'); |       console.log('Chart configuration changed, fetching new data'); | ||||||
| @ -400,13 +402,32 @@ 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, filterParams).subscribe( |     this.dashboardService.getChartData(actualApiUrl, 'doughnut', drilldownConfig.xAxis, drilldownConfig.yAxis, this.connection, parameterField, parameterValue, finalFilterParams).subscribe( | ||||||
|       (data: any) => { |       (data: any) => { | ||||||
|         console.log('Received drilldown data:', data); |         console.log('Received drilldown data:', data); | ||||||
|         if (data === null) { |         if (data === null) { | ||||||
|  | |||||||
| @ -31,6 +31,7 @@ export class DynamicChartComponent implements OnInit, OnChanges { | |||||||
|   @Input() drilldownYAxis: string; |   @Input() drilldownYAxis: string; | ||||||
|   @Input() drilldownParameter: string; // Add drilldown parameter input
 |   @Input() drilldownParameter: string; // Add drilldown parameter input
 | ||||||
|   @Input() baseFilters: any[] = []; // Add base filters input
 |   @Input() baseFilters: any[] = []; // Add base filters input
 | ||||||
|  |   @Input() drilldownFilters: any[] = []; // Add drilldown filters input
 | ||||||
|   // Multi-layer drilldown configuration inputs
 |   // Multi-layer drilldown configuration inputs
 | ||||||
|   @Input() drilldownLayers: any[] = []; // Array of drilldown layer configurations
 |   @Input() drilldownLayers: any[] = []; // Array of drilldown layer configurations
 | ||||||
| 
 | 
 | ||||||
| @ -52,6 +53,7 @@ export class DynamicChartComponent implements OnInit, OnChanges { | |||||||
|     const tableChanged = changes.table && !changes.table.firstChange; |     const tableChanged = changes.table && !changes.table.firstChange; | ||||||
|     const connectionChanged = changes.connection && !changes.connection.firstChange; |     const connectionChanged = changes.connection && !changes.connection.firstChange; | ||||||
|     const baseFiltersChanged = changes.baseFilters && !changes.baseFilters.firstChange; |     const baseFiltersChanged = changes.baseFilters && !changes.baseFilters.firstChange; | ||||||
|  |     const drilldownFiltersChanged = changes.drilldownFilters && !changes.drilldownFilters.firstChange; | ||||||
|     // Drilldown configuration changes
 |     // Drilldown configuration changes
 | ||||||
|     const drilldownEnabledChanged = changes.drilldownEnabled && !changes.drilldownEnabled.firstChange; |     const drilldownEnabledChanged = changes.drilldownEnabled && !changes.drilldownEnabled.firstChange; | ||||||
|     const drilldownApiUrlChanged = changes.drilldownApiUrl && !changes.drilldownApiUrl.firstChange; |     const drilldownApiUrlChanged = changes.drilldownApiUrl && !changes.drilldownApiUrl.firstChange; | ||||||
| @ -60,7 +62,7 @@ export class DynamicChartComponent implements OnInit, OnChanges { | |||||||
|     const drilldownLayersChanged = changes.drilldownLayers && !changes.drilldownLayers.firstChange; |     const drilldownLayersChanged = changes.drilldownLayers && !changes.drilldownLayers.firstChange; | ||||||
|      |      | ||||||
|     // Only fetch data if the actual chart configuration changed and we're not already fetching
 |     // Only fetch data if the actual chart configuration changed and we're not already fetching
 | ||||||
|     if (!this.isFetchingData && (xAxisChanged || yAxisChanged || tableChanged || connectionChanged || baseFiltersChanged || |     if (!this.isFetchingData && (xAxisChanged || yAxisChanged || tableChanged || connectionChanged || baseFiltersChanged || drilldownFiltersChanged || | ||||||
|         drilldownEnabledChanged || drilldownApiUrlChanged || drilldownXAxisChanged || drilldownYAxisChanged || |         drilldownEnabledChanged || drilldownApiUrlChanged || drilldownXAxisChanged || drilldownYAxisChanged || | ||||||
|         drilldownLayersChanged)) { |         drilldownLayersChanged)) { | ||||||
|       console.log('Chart configuration changed, fetching new data'); |       console.log('Chart configuration changed, fetching new data'); | ||||||
| @ -296,13 +298,32 @@ 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, filterParams).subscribe( |     this.dashboardService.getChartData(actualApiUrl, 'dynamic', drilldownConfig.xAxis, drilldownConfig.yAxis, this.connection, parameterField, parameterValue, finalFilterParams).subscribe( | ||||||
|       (data: any) => { |       (data: any) => { | ||||||
|         console.log('Received drilldown data:', data); |         console.log('Received drilldown data:', data); | ||||||
|         if (data === null) { |         if (data === null) { | ||||||
|  | |||||||
| @ -29,6 +29,7 @@ export class FinancialChartComponent implements OnInit, OnChanges { | |||||||
|   @Input() drilldownYAxis: string; |   @Input() drilldownYAxis: string; | ||||||
|   @Input() drilldownParameter: string; // Add drilldown parameter input
 |   @Input() drilldownParameter: string; // Add drilldown parameter input
 | ||||||
|   @Input() baseFilters: any[] = []; // Add base filters input
 |   @Input() baseFilters: any[] = []; // Add base filters input
 | ||||||
|  |   @Input() drilldownFilters: any[] = []; // Add drilldown filters input
 | ||||||
|   // Multi-layer drilldown configuration inputs
 |   // Multi-layer drilldown configuration inputs
 | ||||||
|   @Input() drilldownLayers: any[] = []; // Array of drilldown layer configurations
 |   @Input() drilldownLayers: any[] = []; // Array of drilldown layer configurations
 | ||||||
| 
 | 
 | ||||||
| @ -48,6 +49,7 @@ export class FinancialChartComponent implements OnInit, OnChanges { | |||||||
|     const tableChanged = changes.table && !changes.table.firstChange; |     const tableChanged = changes.table && !changes.table.firstChange; | ||||||
|     const connectionChanged = changes.connection && !changes.connection.firstChange; |     const connectionChanged = changes.connection && !changes.connection.firstChange; | ||||||
|     const baseFiltersChanged = changes.baseFilters && !changes.baseFilters.firstChange; |     const baseFiltersChanged = changes.baseFilters && !changes.baseFilters.firstChange; | ||||||
|  |     const drilldownFiltersChanged = changes.drilldownFilters && !changes.drilldownFilters.firstChange; | ||||||
|     // Drilldown configuration changes
 |     // Drilldown configuration changes
 | ||||||
|     const drilldownEnabledChanged = changes.drilldownEnabled && !changes.drilldownEnabled.firstChange; |     const drilldownEnabledChanged = changes.drilldownEnabled && !changes.drilldownEnabled.firstChange; | ||||||
|     const drilldownApiUrlChanged = changes.drilldownApiUrl && !changes.drilldownApiUrl.firstChange; |     const drilldownApiUrlChanged = changes.drilldownApiUrl && !changes.drilldownApiUrl.firstChange; | ||||||
| @ -56,7 +58,7 @@ export class FinancialChartComponent implements OnInit, OnChanges { | |||||||
|     const drilldownLayersChanged = changes.drilldownLayers && !changes.drilldownLayers.firstChange; |     const drilldownLayersChanged = changes.drilldownLayers && !changes.drilldownLayers.firstChange; | ||||||
|      |      | ||||||
|     // Only fetch data if the actual chart configuration changed and we're not already fetching
 |     // Only fetch data if the actual chart configuration changed and we're not already fetching
 | ||||||
|     if (!this.isFetchingData && (xAxisChanged || yAxisChanged || tableChanged || connectionChanged || baseFiltersChanged || |     if (!this.isFetchingData && (xAxisChanged || yAxisChanged || tableChanged || connectionChanged || baseFiltersChanged || drilldownFiltersChanged || | ||||||
|         drilldownEnabledChanged || drilldownApiUrlChanged || drilldownXAxisChanged || drilldownYAxisChanged || |         drilldownEnabledChanged || drilldownApiUrlChanged || drilldownXAxisChanged || drilldownYAxisChanged || | ||||||
|         drilldownLayersChanged)) { |         drilldownLayersChanged)) { | ||||||
|       console.log('Chart configuration changed, fetching new data'); |       console.log('Chart configuration changed, fetching new data'); | ||||||
| @ -287,13 +289,32 @@ 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, filterParams).subscribe( |     this.dashboardService.getChartData(actualApiUrl, 'financial', drilldownConfig.xAxis, drilldownConfig.yAxis, this.connection, parameterField, parameterValue, finalFilterParams).subscribe( | ||||||
|       (data: any) => { |       (data: any) => { | ||||||
|         console.log('Received drilldown data:', data); |         console.log('Received drilldown data:', data); | ||||||
|         if (data === null) { |         if (data === null) { | ||||||
|  | |||||||
| @ -29,6 +29,7 @@ export class LineChartComponent implements OnInit, OnChanges { | |||||||
|   @Input() drilldownYAxis: string; |   @Input() drilldownYAxis: string; | ||||||
|   @Input() drilldownParameter: string; // Add drilldown parameter input
 |   @Input() drilldownParameter: string; // Add drilldown parameter input
 | ||||||
|   @Input() baseFilters: any[] = []; // Add base filters input
 |   @Input() baseFilters: any[] = []; // Add base filters input
 | ||||||
|  |   @Input() drilldownFilters: any[] = []; // Add drilldown filters input
 | ||||||
|   // Multi-layer drilldown configuration inputs
 |   // Multi-layer drilldown configuration inputs
 | ||||||
|   @Input() drilldownLayers: any[] = []; // Array of drilldown layer configurations
 |   @Input() drilldownLayers: any[] = []; // Array of drilldown layer configurations
 | ||||||
| 
 | 
 | ||||||
| @ -98,6 +99,7 @@ export class LineChartComponent implements OnInit, OnChanges { | |||||||
|     const tableChanged = changes.table && !changes.table.firstChange; |     const tableChanged = changes.table && !changes.table.firstChange; | ||||||
|     const connectionChanged = changes.connection && !changes.connection.firstChange; |     const connectionChanged = changes.connection && !changes.connection.firstChange; | ||||||
|     const baseFiltersChanged = changes.baseFilters && !changes.baseFilters.firstChange; |     const baseFiltersChanged = changes.baseFilters && !changes.baseFilters.firstChange; | ||||||
|  |     const drilldownFiltersChanged = changes.drilldownFilters && !changes.drilldownFilters.firstChange; | ||||||
|     // Drilldown configuration changes
 |     // Drilldown configuration changes
 | ||||||
|     const drilldownEnabledChanged = changes.drilldownEnabled && !changes.drilldownEnabled.firstChange; |     const drilldownEnabledChanged = changes.drilldownEnabled && !changes.drilldownEnabled.firstChange; | ||||||
|     const drilldownApiUrlChanged = changes.drilldownApiUrl && !changes.drilldownApiUrl.firstChange; |     const drilldownApiUrlChanged = changes.drilldownApiUrl && !changes.drilldownApiUrl.firstChange; | ||||||
| @ -106,7 +108,7 @@ export class LineChartComponent implements OnInit, OnChanges { | |||||||
|     const drilldownLayersChanged = changes.drilldownLayers && !changes.drilldownLayers.firstChange; |     const drilldownLayersChanged = changes.drilldownLayers && !changes.drilldownLayers.firstChange; | ||||||
|      |      | ||||||
|     // Only fetch data if the actual chart configuration changed and we're not already fetching
 |     // Only fetch data if the actual chart configuration changed and we're not already fetching
 | ||||||
|     if (!this.isFetchingData && (xAxisChanged || yAxisChanged || tableChanged || connectionChanged || baseFiltersChanged || |     if (!this.isFetchingData && (xAxisChanged || yAxisChanged || tableChanged || connectionChanged || baseFiltersChanged || drilldownFiltersChanged || | ||||||
|         drilldownEnabledChanged || drilldownApiUrlChanged || drilldownXAxisChanged || drilldownYAxisChanged || |         drilldownEnabledChanged || drilldownApiUrlChanged || drilldownXAxisChanged || drilldownYAxisChanged || | ||||||
|         drilldownLayersChanged)) { |         drilldownLayersChanged)) { | ||||||
|       console.log('Chart configuration changed, fetching new data'); |       console.log('Chart configuration changed, fetching new data'); | ||||||
| @ -311,13 +313,32 @@ 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, filterParams).subscribe( |     this.dashboardService.getChartData(actualApiUrl, 'line', drilldownConfig.xAxis, drilldownConfig.yAxis, this.connection, parameterField, parameterValue, finalFilterParams).subscribe( | ||||||
|       (data: any) => { |       (data: any) => { | ||||||
|         console.log('Received drilldown data:', data); |         console.log('Received drilldown data:', data); | ||||||
|         if (data === null) { |         if (data === null) { | ||||||
|  | |||||||
| @ -29,6 +29,7 @@ export class PieChartComponent implements OnInit, OnChanges, AfterViewChecked { | |||||||
|   @Input() drilldownYAxis: string; |   @Input() drilldownYAxis: string; | ||||||
|   @Input() drilldownParameter: string; // Add drilldown parameter input
 |   @Input() drilldownParameter: string; // Add drilldown parameter input
 | ||||||
|   @Input() baseFilters: any[] = []; // Add base filters input
 |   @Input() baseFilters: any[] = []; // Add base filters input
 | ||||||
|  |   @Input() drilldownFilters: any[] = []; // Add drilldown filters input
 | ||||||
|   // Multi-layer drilldown configuration inputs
 |   // Multi-layer drilldown configuration inputs
 | ||||||
|   @Input() drilldownLayers: any[] = []; // Array of drilldown layer configurations
 |   @Input() drilldownLayers: any[] = []; // Array of drilldown layer configurations
 | ||||||
| 
 | 
 | ||||||
| @ -122,6 +123,7 @@ export class PieChartComponent implements OnInit, OnChanges, AfterViewChecked { | |||||||
|     const tableChanged = changes.table && !changes.table.firstChange; |     const tableChanged = changes.table && !changes.table.firstChange; | ||||||
|     const connectionChanged = changes.connection && !changes.connection.firstChange; |     const connectionChanged = changes.connection && !changes.connection.firstChange; | ||||||
|     const baseFiltersChanged = changes.baseFilters && !changes.baseFilters.firstChange; |     const baseFiltersChanged = changes.baseFilters && !changes.baseFilters.firstChange; | ||||||
|  |     const drilldownFiltersChanged = changes.drilldownFilters && !changes.drilldownFilters.firstChange; | ||||||
|     // Drilldown configuration changes
 |     // Drilldown configuration changes
 | ||||||
|     const drilldownEnabledChanged = changes.drilldownEnabled && !changes.drilldownEnabled.firstChange; |     const drilldownEnabledChanged = changes.drilldownEnabled && !changes.drilldownEnabled.firstChange; | ||||||
|     const drilldownApiUrlChanged = changes.drilldownApiUrl && !changes.drilldownApiUrl.firstChange; |     const drilldownApiUrlChanged = changes.drilldownApiUrl && !changes.drilldownApiUrl.firstChange; | ||||||
| @ -130,7 +132,7 @@ export class PieChartComponent implements OnInit, OnChanges, AfterViewChecked { | |||||||
|     const drilldownLayersChanged = changes.drilldownLayers && !changes.drilldownLayers.firstChange; |     const drilldownLayersChanged = changes.drilldownLayers && !changes.drilldownLayers.firstChange; | ||||||
|      |      | ||||||
|     // Only fetch data if the actual chart configuration changed and we're not already fetching
 |     // Only fetch data if the actual chart configuration changed and we're not already fetching
 | ||||||
|     if (!this.isFetchingData && (xAxisChanged || yAxisChanged || tableChanged || connectionChanged || baseFiltersChanged || |     if (!this.isFetchingData && (xAxisChanged || yAxisChanged || tableChanged || connectionChanged || baseFiltersChanged || drilldownFiltersChanged || | ||||||
|         drilldownEnabledChanged || drilldownApiUrlChanged || drilldownXAxisChanged || drilldownYAxisChanged || |         drilldownEnabledChanged || drilldownApiUrlChanged || drilldownXAxisChanged || drilldownYAxisChanged || | ||||||
|         drilldownLayersChanged)) { |         drilldownLayersChanged)) { | ||||||
|       console.log('Chart configuration changed, fetching new data'); |       console.log('Chart configuration changed, fetching new data'); | ||||||
| @ -360,13 +362,32 @@ 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, filterParams).subscribe( |     this.dashboardService.getChartData(actualApiUrl, 'pie', drilldownConfig.xAxis, drilldownConfig.yAxis, this.connection, parameterField, parameterValue, finalFilterParams).subscribe( | ||||||
|       (data: any) => { |       (data: any) => { | ||||||
|         console.log('Received drilldown data:', data); |         console.log('Received drilldown data:', data); | ||||||
|         if (data === null) { |         if (data === null) { | ||||||
|  | |||||||
| @ -1,28 +1,10 @@ | |||||||
|  | 
 | ||||||
| <div style="display: block"> | <div style="display: block"> | ||||||
|   <!-- Drilldown mode indicator --> |   <canvas baseChart | ||||||
|   <div *ngIf="currentDrilldownLevel > 0" style="background-color: #e0e0e0; padding: 5px; margin-bottom: 10px; border-radius: 4px; text-align: center;"> |     [datasets]="polarAreaChartData" | ||||||
|     <span style="font-weight: bold; color: #333;">Drilldown Level: {{currentDrilldownLevel}}</span> |     [labels]="polarAreaChartLabels" | ||||||
|     <button (click)="navigateBack()" style="margin-left: 10px; padding: 2px 8px; background-color: #007cba; color: white; border: none; border-radius: 3px; cursor: pointer;"> |     [type]="polarAreaChartType" | ||||||
|       Back to Level {{currentDrilldownLevel - 1}} |     (chartHover)="chartHovered($event)" | ||||||
|     </button> |    (chartClick)="chartClicked($event)"> | ||||||
|     <button (click)="resetToOriginalData()" style="margin-left: 10px; padding: 2px 8px; background-color: #dc3545; color: white; border: none; border-radius: 3px; cursor: pointer;"> |   </canvas> | ||||||
|       Back to Main View | </div> | ||||||
|     </button> |  | ||||||
|   </div> |  | ||||||
|    |  | ||||||
|   <!-- No data message --> |  | ||||||
|   <div *ngIf="noDataAvailable" style="text-align: center; padding: 20px; color: #666; font-style: italic;"> |  | ||||||
|     No data available |  | ||||||
|   </div> |  | ||||||
|    |  | ||||||
|   <!-- Chart display --> |  | ||||||
|   <div *ngIf="!noDataAvailable"> |  | ||||||
|     <canvas baseChart |  | ||||||
|       [data]="polarAreaChartData" |  | ||||||
|       [labels]="polarAreaChartLabels" |  | ||||||
|       [type]="polarAreaChartType" |  | ||||||
|       (chartHover)="chartHovered($event)" |  | ||||||
|       (chartClick)="chartClicked($event)"> |  | ||||||
|     </canvas> |  | ||||||
|   </div> |  | ||||||
| </div> |  | ||||||
|  | |||||||
| @ -0,0 +1,18 @@ | |||||||
|  | // Polar Chart Component Styles | ||||||
|  | div[style*="display: block"] { | ||||||
|  |   position: relative; | ||||||
|  |   width: 100%; | ||||||
|  |   height: 100%; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | canvas { | ||||||
|  |   max-width: 100%; | ||||||
|  |   max-height: 100%; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Ensure the chart container has proper sizing | ||||||
|  | :host { | ||||||
|  |   display: block; | ||||||
|  |   width: 100%; | ||||||
|  |   height: 100%; | ||||||
|  | } | ||||||
| @ -1,12 +1,13 @@ | |||||||
| import { Component, OnInit, Input, OnChanges, SimpleChanges } from '@angular/core'; | import { Component, Input, OnInit, OnChanges, OnDestroy, SimpleChanges } from '@angular/core'; | ||||||
| import { Dashboard3Service } from 'src/app/services/builder/dashboard3.service'; | import { Dashboard3Service } from '../../../../../../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 { | export class PolarChartComponent implements OnInit, OnChanges, OnDestroy { | ||||||
|   @Input() xAxis: string; |   @Input() xAxis: string; | ||||||
|   @Input() yAxis: string | string[]; |   @Input() yAxis: string | string[]; | ||||||
|   @Input() table: string; |   @Input() table: string; | ||||||
| @ -29,11 +30,30 @@ export class PolarChartComponent implements OnInit, OnChanges { | |||||||
|   @Input() drilldownYAxis: string; |   @Input() drilldownYAxis: string; | ||||||
|   @Input() drilldownParameter: string; // Add drilldown parameter input
 |   @Input() drilldownParameter: string; // Add drilldown parameter input
 | ||||||
|   @Input() baseFilters: any[] = []; // Add base filters input
 |   @Input() baseFilters: any[] = []; // Add base filters input
 | ||||||
|  |   @Input() drilldownFilters: any[] = []; // Add drilldown filters input
 | ||||||
|   // Multi-layer drilldown configuration inputs
 |   // Multi-layer drilldown configuration inputs
 | ||||||
|   @Input() drilldownLayers: any[] = []; // Array of drilldown layer configurations
 |   @Input() drilldownLayers: any[] = []; // Array of drilldown layer configurations
 | ||||||
| 
 | 
 | ||||||
|   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(); | ||||||
| @ -48,6 +68,7 @@ export class PolarChartComponent implements OnInit, OnChanges { | |||||||
|     const tableChanged = changes.table && !changes.table.firstChange; |     const tableChanged = changes.table && !changes.table.firstChange; | ||||||
|     const connectionChanged = changes.connection && !changes.connection.firstChange; |     const connectionChanged = changes.connection && !changes.connection.firstChange; | ||||||
|     const baseFiltersChanged = changes.baseFilters && !changes.baseFilters.firstChange; |     const baseFiltersChanged = changes.baseFilters && !changes.baseFilters.firstChange; | ||||||
|  |     const drilldownFiltersChanged = changes.drilldownFilters && !changes.drilldownFilters.firstChange; | ||||||
|     // Drilldown configuration changes
 |     // Drilldown configuration changes
 | ||||||
|     const drilldownEnabledChanged = changes.drilldownEnabled && !changes.drilldownEnabled.firstChange; |     const drilldownEnabledChanged = changes.drilldownEnabled && !changes.drilldownEnabled.firstChange; | ||||||
|     const drilldownApiUrlChanged = changes.drilldownApiUrl && !changes.drilldownApiUrl.firstChange; |     const drilldownApiUrlChanged = changes.drilldownApiUrl && !changes.drilldownApiUrl.firstChange; | ||||||
| @ -56,33 +77,14 @@ export class PolarChartComponent implements OnInit, OnChanges { | |||||||
|     const drilldownLayersChanged = changes.drilldownLayers && !changes.drilldownLayers.firstChange; |     const drilldownLayersChanged = changes.drilldownLayers && !changes.drilldownLayers.firstChange; | ||||||
|      |      | ||||||
|     // Only fetch data if the actual chart configuration changed and we're not already fetching
 |     // Only fetch data if the actual chart configuration changed and we're not already fetching
 | ||||||
|     if (!this.isFetchingData && (xAxisChanged || yAxisChanged || tableChanged || connectionChanged || baseFiltersChanged || |     if (!this.isFetchingData && (xAxisChanged || yAxisChanged || tableChanged || connectionChanged || baseFiltersChanged || drilldownFiltersChanged || | ||||||
|         drilldownEnabledChanged || drilldownApiUrlChanged || drilldownXAxisChanged || drilldownYAxisChanged || |         drilldownEnabledChanged || drilldownApiUrlChanged || drilldownXAxisChanged || drilldownYAxisChanged || | ||||||
|         drilldownLayersChanged)) { |         drilldownLayersChanged)) { | ||||||
|       console.log('Chart configuration changed, fetching new data'); |       console.log('Chart configuration changed, fetching new data'); | ||||||
|       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; | ||||||
| @ -131,6 +133,8 @@ export class PolarChartComponent implements OnInit, OnChanges { | |||||||
|             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; | ||||||
| @ -141,26 +145,36 @@ export class PolarChartComponent implements OnInit, OnChanges { | |||||||
|             // 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
 | ||||||
|                 return isNaN(Number(value)) ? 0 : Number(value); |                 const numValue = 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
 | ||||||
|               return isNaN(Number(value)) ? 0 : Number(value); |               const numValue = 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 }); | ||||||
| @ -169,6 +183,8 @@ export class PolarChartComponent implements OnInit, OnChanges { | |||||||
|             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; | ||||||
| @ -178,6 +194,8 @@ export class PolarChartComponent implements OnInit, OnChanges { | |||||||
|           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
 | ||||||
| @ -188,6 +206,8 @@ export class PolarChartComponent implements OnInit, OnChanges { | |||||||
|       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; | ||||||
|     } |     } | ||||||
| @ -285,13 +305,32 @@ export class PolarChartComponent 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/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, filterParams).subscribe( |     this.dashboardService.getChartData(actualApiUrl, 'polar', drilldownConfig.xAxis, drilldownConfig.yAxis, this.connection, parameterField, parameterValue, finalFilterParams).subscribe( | ||||||
|       (data: any) => { |       (data: any) => { | ||||||
|         console.log('Received drilldown data:', data); |         console.log('Received drilldown data:', data); | ||||||
|         if (data === null) { |         if (data === null) { | ||||||
| @ -307,26 +346,36 @@ export class PolarChartComponent implements OnInit, OnChanges { | |||||||
|           // 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
 | ||||||
|               return isNaN(Number(value)) ? 0 : Number(value); |               const numValue = 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
 | ||||||
|             return isNaN(Number(value)) ? 0 : Number(value); |             const numValue = 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 }); | ||||||
| @ -335,6 +384,8 @@ export class PolarChartComponent implements OnInit, OnChanges { | |||||||
|           this.noDataAvailable = true; |           this.noDataAvailable = true; | ||||||
|           this.polarAreaChartLabels = []; |           this.polarAreaChartLabels = []; | ||||||
|           this.polarAreaChartData = []; |           this.polarAreaChartData = []; | ||||||
|  |           // Validate and sanitize data
 | ||||||
|  |           this.validateChartData(); | ||||||
|         } |         } | ||||||
|       }, |       }, | ||||||
|       (error) => { |       (error) => { | ||||||
| @ -403,6 +454,58 @@ export class PolarChartComponent implements OnInit, OnChanges { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   /** | ||||||
|  |    * 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); | ||||||
| @ -491,4 +594,8 @@ export class PolarChartComponent implements OnInit, OnChanges { | |||||||
|   public chartHovered(e: any): void { |   public chartHovered(e: any): void { | ||||||
|     console.log(e); |     console.log(e); | ||||||
|   } |   } | ||||||
|  |    | ||||||
|  |   ngOnDestroy(): void { | ||||||
|  |     // Clean up any subscriptions if needed
 | ||||||
|  |   } | ||||||
| } | } | ||||||
| @ -29,6 +29,7 @@ export class RadarChartComponent implements OnInit, OnChanges { | |||||||
|   @Input() drilldownYAxis: string; |   @Input() drilldownYAxis: string; | ||||||
|   @Input() drilldownParameter: string; // Add drilldown parameter input
 |   @Input() drilldownParameter: string; // Add drilldown parameter input
 | ||||||
|   @Input() baseFilters: any[] = []; // Add base filters input
 |   @Input() baseFilters: any[] = []; // Add base filters input
 | ||||||
|  |   @Input() drilldownFilters: any[] = []; // Add drilldown filters input
 | ||||||
|   // Multi-layer drilldown configuration inputs
 |   // Multi-layer drilldown configuration inputs
 | ||||||
|   @Input() drilldownLayers: any[] = []; // Array of drilldown layer configurations
 |   @Input() drilldownLayers: any[] = []; // Array of drilldown layer configurations
 | ||||||
| 
 | 
 | ||||||
| @ -76,6 +77,7 @@ export class RadarChartComponent implements OnInit, OnChanges { | |||||||
|     const tableChanged = changes.table && !changes.table.firstChange; |     const tableChanged = changes.table && !changes.table.firstChange; | ||||||
|     const connectionChanged = changes.connection && !changes.connection.firstChange; |     const connectionChanged = changes.connection && !changes.connection.firstChange; | ||||||
|     const baseFiltersChanged = changes.baseFilters && !changes.baseFilters.firstChange; |     const baseFiltersChanged = changes.baseFilters && !changes.baseFilters.firstChange; | ||||||
|  |     const drilldownFiltersChanged = changes.drilldownFilters && !changes.drilldownFilters.firstChange; | ||||||
|     // Drilldown configuration changes
 |     // Drilldown configuration changes
 | ||||||
|     const drilldownEnabledChanged = changes.drilldownEnabled && !changes.drilldownEnabled.firstChange; |     const drilldownEnabledChanged = changes.drilldownEnabled && !changes.drilldownEnabled.firstChange; | ||||||
|     const drilldownApiUrlChanged = changes.drilldownApiUrl && !changes.drilldownApiUrl.firstChange; |     const drilldownApiUrlChanged = changes.drilldownApiUrl && !changes.drilldownApiUrl.firstChange; | ||||||
| @ -84,7 +86,7 @@ export class RadarChartComponent implements OnInit, OnChanges { | |||||||
|     const drilldownLayersChanged = changes.drilldownLayers && !changes.drilldownLayers.firstChange; |     const drilldownLayersChanged = changes.drilldownLayers && !changes.drilldownLayers.firstChange; | ||||||
|      |      | ||||||
|     // Only fetch data if the actual chart configuration changed and we're not already fetching
 |     // Only fetch data if the actual chart configuration changed and we're not already fetching
 | ||||||
|     if (!this.isFetchingData && (xAxisChanged || yAxisChanged || tableChanged || connectionChanged || baseFiltersChanged || |     if (!this.isFetchingData && (xAxisChanged || yAxisChanged || tableChanged || connectionChanged || baseFiltersChanged || drilldownFiltersChanged || | ||||||
|         drilldownEnabledChanged || drilldownApiUrlChanged || drilldownXAxisChanged || drilldownYAxisChanged || |         drilldownEnabledChanged || drilldownApiUrlChanged || drilldownXAxisChanged || drilldownYAxisChanged || | ||||||
|         drilldownLayersChanged)) { |         drilldownLayersChanged)) { | ||||||
|       console.log('Chart configuration changed, fetching new data'); |       console.log('Chart configuration changed, fetching new data'); | ||||||
| @ -296,13 +298,32 @@ 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, filterParams).subscribe( |     this.dashboardService.getChartData(actualApiUrl, 'radar', drilldownConfig.xAxis, drilldownConfig.yAxis, this.connection, parameterField, parameterValue, finalFilterParams).subscribe( | ||||||
|       (data: any) => { |       (data: any) => { | ||||||
|         console.log('Received drilldown data:', data); |         console.log('Received drilldown data:', data); | ||||||
|         if (data === null) { |         if (data === null) { | ||||||
|  | |||||||
| @ -30,6 +30,7 @@ export class ScatterChartComponent implements OnInit, OnChanges { | |||||||
|   @Input() drilldownYAxis: string; |   @Input() drilldownYAxis: string; | ||||||
|   @Input() drilldownParameter: string; // Add drilldown parameter input
 |   @Input() drilldownParameter: string; // Add drilldown parameter input
 | ||||||
|   @Input() baseFilters: any[] = []; // Add base filters input
 |   @Input() baseFilters: any[] = []; // Add base filters input
 | ||||||
|  |   @Input() drilldownFilters: any[] = []; // Add drilldown filters input
 | ||||||
|   // Multi-layer drilldown configuration inputs
 |   // Multi-layer drilldown configuration inputs
 | ||||||
|   @Input() drilldownLayers: any[] = []; // Array of drilldown layer configurations
 |   @Input() drilldownLayers: any[] = []; // Array of drilldown layer configurations
 | ||||||
| 
 | 
 | ||||||
| @ -49,6 +50,7 @@ export class ScatterChartComponent implements OnInit, OnChanges { | |||||||
|     const tableChanged = changes.table && !changes.table.firstChange; |     const tableChanged = changes.table && !changes.table.firstChange; | ||||||
|     const connectionChanged = changes.connection && !changes.connection.firstChange; |     const connectionChanged = changes.connection && !changes.connection.firstChange; | ||||||
|     const baseFiltersChanged = changes.baseFilters && !changes.baseFilters.firstChange; |     const baseFiltersChanged = changes.baseFilters && !changes.baseFilters.firstChange; | ||||||
|  |     const drilldownFiltersChanged = changes.drilldownFilters && !changes.drilldownFilters.firstChange; | ||||||
|     // Drilldown configuration changes
 |     // Drilldown configuration changes
 | ||||||
|     const drilldownEnabledChanged = changes.drilldownEnabled && !changes.drilldownEnabled.firstChange; |     const drilldownEnabledChanged = changes.drilldownEnabled && !changes.drilldownEnabled.firstChange; | ||||||
|     const drilldownApiUrlChanged = changes.drilldownApiUrl && !changes.drilldownApiUrl.firstChange; |     const drilldownApiUrlChanged = changes.drilldownApiUrl && !changes.drilldownApiUrl.firstChange; | ||||||
| @ -57,7 +59,7 @@ export class ScatterChartComponent implements OnInit, OnChanges { | |||||||
|     const drilldownLayersChanged = changes.drilldownLayers && !changes.drilldownLayers.firstChange; |     const drilldownLayersChanged = changes.drilldownLayers && !changes.drilldownLayers.firstChange; | ||||||
|      |      | ||||||
|     // Only fetch data if the actual chart configuration changed and we're not already fetching
 |     // Only fetch data if the actual chart configuration changed and we're not already fetching
 | ||||||
|     if (!this.isFetchingData && (xAxisChanged || yAxisChanged || tableChanged || connectionChanged || baseFiltersChanged || |     if (!this.isFetchingData && (xAxisChanged || yAxisChanged || tableChanged || connectionChanged || baseFiltersChanged || drilldownFiltersChanged || | ||||||
|         drilldownEnabledChanged || drilldownApiUrlChanged || drilldownXAxisChanged || drilldownYAxisChanged || |         drilldownEnabledChanged || drilldownApiUrlChanged || drilldownXAxisChanged || drilldownYAxisChanged || | ||||||
|         drilldownLayersChanged)) { |         drilldownLayersChanged)) { | ||||||
|       console.log('Chart configuration changed, fetching new data'); |       console.log('Chart configuration changed, fetching new data'); | ||||||
| @ -285,13 +287,32 @@ export class ScatterChartComponent 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/scatter?tableName=${actualApiUrl}&xAxis=${drilldownConfig.xAxis}&yAxes=${drilldownConfig.yAxis}${this.connection ? `&sureId=${this.connection}` : ''}`; |     const url = `chart/getdashjson/scatter?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, 'scatter', drilldownConfig.xAxis, drilldownConfig.yAxis, this.connection, parameterField, parameterValue, filterParams).subscribe( |     this.dashboardService.getChartData(actualApiUrl, 'scatter', drilldownConfig.xAxis, drilldownConfig.yAxis, this.connection, parameterField, parameterValue, finalFilterParams).subscribe( | ||||||
|       (data: any) => { |       (data: any) => { | ||||||
|         console.log('Received drilldown data:', data); |         console.log('Received drilldown data:', data); | ||||||
|         if (data === null) { |         if (data === null) { | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user