From 807058e40da6a4afaeaec8a88a815f52588e384a Mon Sep 17 00:00:00 2001 From: Gaurav Kumar Date: Sat, 1 Nov 2025 16:20:59 +0530 Subject: [PATCH] chart --- .../unified-chart.component.html | 110 +++++++----- .../unified-chart.component.scss | 35 +++- .../unified-chart/unified-chart.component.ts | 162 ++++++++++++++++-- 3 files changed, 246 insertions(+), 61 deletions(-) diff --git a/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/gadgets/unified-chart/unified-chart.component.html b/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/gadgets/unified-chart/unified-chart.component.html index f03b8f2..3edb352 100644 --- a/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/gadgets/unified-chart/unified-chart.component.html +++ b/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/gadgets/unified-chart/unified-chart.component.html @@ -13,6 +13,19 @@

{{ charttitle }}

+ +
+ + + + {{ showFilters ? 'Hide Filters' : 'Show Filters' }} + +
+
@@ -131,23 +144,23 @@
- -
+ +
Filters
-
- +
+ + class="form-control" placeholder="Enter {{ filter.field || 'value' }}">
- + -
- +
@@ -203,22 +219,22 @@
-
+
Drilldown Filters
-
- +
+ + class="form-control" placeholder="Enter {{ filter.field || 'value' }}">
- + -
- +
@@ -274,22 +293,22 @@
-
+
Layer Filters
-
- +
+ + class="form-control" placeholder="Enter {{ filter.field || 'value' }}">
- + -
- +
@@ -345,7 +367,7 @@
-
+
diff --git a/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/gadgets/unified-chart/unified-chart.component.scss b/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/gadgets/unified-chart/unified-chart.component.scss index 44cc12f..4cd6c2e 100644 --- a/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/gadgets/unified-chart/unified-chart.component.scss +++ b/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/gadgets/unified-chart/unified-chart.component.scss @@ -30,16 +30,15 @@ .chart-wrapper { position: relative; height: calc(100% - 100px); - min-height: 400px; // Increased minimum height for better visibility - padding: 10px; // Add padding to create space around the chart + min-height: 400px; + padding: 10px; } -// Specific container for chart canvas elements .chart-canvas-container { position: relative; height: 100%; width: 100%; - padding: 15px; // Add padding around the canvas for better spacing + padding: 15px; box-sizing: border-box; canvas { @@ -49,6 +48,33 @@ } } +.filter-toggle-icon { + display: flex; + align-items: center; + justify-content: flex-end; + padding: 5px; + cursor: pointer; + + clr-icon { + transition: color 0.3s ease; + + &:hover { + color: #007cba !important; + } + } + + span { + margin-left: 5px; + font-size: 12px; + color: #666; + transition: color 0.3s ease; + } + + &:hover span { + color: #007cba; + } +} + .filters-section { margin-top: 20px; padding: 15px; @@ -262,7 +288,6 @@ 100% { transform: rotate(360deg); } } -// Responsive adjustments @media (max-width: 768px) { .filters-container { flex-direction: column; diff --git a/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/gadgets/unified-chart/unified-chart.component.ts b/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/gadgets/unified-chart/unified-chart.component.ts index aba11a2..cb163f6 100644 --- a/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/gadgets/unified-chart/unified-chart.component.ts +++ b/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/gadgets/unified-chart/unified-chart.component.ts @@ -61,6 +61,9 @@ export class UnifiedChartComponent implements OnInit, OnChanges, OnDestroy { currentDrilldownLevel: number = 0; originalChartData: any = {}; + // Filter visibility toggle + showFilters: boolean = false; + // Flag to prevent infinite loops private isFetchingData: boolean = false; @@ -85,6 +88,13 @@ export class UnifiedChartComponent implements OnInit, OnChanges, OnDestroy { }) ); + // Initialize filter values if they haven't been initialized yet + if (!this.filtersInitialized) { + this.initializeFilterValues(); + this.filtersInitialized = true; + } + + // Initialize chart options with default structure this.initializeChartOptions(); this.fetchChartData(); } @@ -92,6 +102,17 @@ export class UnifiedChartComponent implements OnInit, OnChanges, OnDestroy { ngOnChanges(changes: SimpleChanges): void { console.log('UnifiedChartComponent input changes:', changes); + // Log all input values for debugging + console.log('Current input values:', { + chartType: this.chartType, + xAxis: this.xAxis, + yAxis: this.yAxis, + table: this.table, + baseFilters: this.baseFilters, + drilldownFilters: this.drilldownFilters, + drilldownLayers: this.drilldownLayers + }); + // Initialize filter values if they haven't been initialized yet if (!this.filtersInitialized && (changes.baseFilters || changes.drilldownFilters || changes.drilldownLayers)) { this.initializeFilterValues(); @@ -114,6 +135,36 @@ export class UnifiedChartComponent implements OnInit, OnChanges, OnDestroy { const drilldownYAxisChanged = changes.drilldownYAxis && !changes.drilldownYAxis.firstChange; const drilldownLayersChanged = changes.drilldownLayers && !changes.drilldownLayers.firstChange; + // Log base filters changes for debugging + if (baseFiltersChanged) { + console.log('Base filters changed:', changes.baseFilters); + console.log('Current base filters:', this.baseFilters); + // Log detailed information about each filter + if (this.baseFilters && Array.isArray(this.baseFilters)) { + this.baseFilters.forEach((filter, index) => { + console.log(`Base filter ${index} details:`, { + field: filter.field, + value: filter.value, + type: filter.type, + options: filter.options + }); + }); + } + } + + // Also log when baseFilters is not changed but we still have filters + if (!baseFiltersChanged && this.baseFilters && this.baseFilters.length > 0) { + console.log('Base filters present but not changed, logging current state:'); + this.baseFilters.forEach((filter, index) => { + console.log(`Base filter ${index} details:`, { + field: filter.field, + value: filter.value, + type: filter.type, + options: filter.options + }); + }); + } + // Only fetch data if the actual chart configuration changed and we're not already fetching if (!this.isFetchingData && (chartTypeChanged || xAxisChanged || yAxisChanged || tableChanged || connectionChanged || baseFiltersChanged || drilldownFiltersChanged || drilldownEnabledChanged || drilldownApiUrlChanged || drilldownXAxisChanged || drilldownYAxisChanged || @@ -126,7 +177,18 @@ export class UnifiedChartComponent implements OnInit, OnChanges, OnDestroy { // Update legend visibility if it changed if (changes.chartlegend !== undefined) { this.chartLegend = changes.chartlegend.currentValue; - this.chartOptions.plugins.legend.display = this.chartLegend; + // Ensure chartOptions and required structures exist before accessing legend + if (!this.chartOptions) { + this.chartOptions = {}; + } + if (!this.chartOptions.plugins) { + this.chartOptions.plugins = {}; + } + if (!this.chartOptions.plugins.legend) { + this.chartOptions.plugins.legend = { display: this.chartLegend }; + } else { + this.chartOptions.plugins.legend.display = this.chartLegend; + } console.log('Chart legend changed to:', this.chartLegend); } } @@ -141,13 +203,30 @@ export class UnifiedChartComponent implements OnInit, OnChanges, OnDestroy { } } + // Check if filters are available + hasFilters(): boolean { + const hasBaseFilters = this.baseFilters && this.baseFilters.length > 0; + console.log('Checking for filters - baseFilters:', this.baseFilters, 'hasBaseFilters:', hasBaseFilters); + return hasBaseFilters; + } + + // Toggle filter visibility + toggleFilters(): void { + console.log('Toggling filters. Current state:', this.showFilters); + console.log('Base filters available:', this.hasFilters()); + this.showFilters = !this.showFilters; + console.log('New state:', this.showFilters); + } + // Initialize filter values with proper default values based on type private initializeFilterValues(): void { console.log('Initializing filter values'); + console.log('Base filters before initialization:', this.baseFilters); // Initialize base filters - if (this.baseFilters) { - this.baseFilters.forEach(filter => { + if (this.baseFilters && Array.isArray(this.baseFilters)) { + this.baseFilters.forEach((filter, index) => { + console.log(`Processing base filter ${index}:`, filter); if (filter.value === undefined || filter.value === null) { switch (filter.type) { case 'multiselect': @@ -162,13 +241,22 @@ export class UnifiedChartComponent implements OnInit, OnChanges, OnDestroy { default: filter.value = ''; } + console.log(`Initialized base filter ${index} value to:`, filter.value); + } else { + console.log(`Base filter ${index} already has value:`, filter.value); } }); + } else { + // Initialize as empty array if not provided + this.baseFilters = []; } + console.log('Base filters after initialization:', this.baseFilters); + // Initialize drilldown filters - if (this.drilldownFilters) { - this.drilldownFilters.forEach(filter => { + if (this.drilldownFilters && Array.isArray(this.drilldownFilters)) { + this.drilldownFilters.forEach((filter, index) => { + console.log(`Processing drilldown filter ${index}:`, filter); if (filter.value === undefined || filter.value === null) { switch (filter.type) { case 'multiselect': @@ -183,15 +271,23 @@ export class UnifiedChartComponent implements OnInit, OnChanges, OnDestroy { default: filter.value = ''; } + console.log(`Initialized drilldown filter ${index} value to:`, filter.value); + } else { + console.log(`Drilldown filter ${index} already has value:`, filter.value); } }); + } else { + // Initialize as empty array if not provided + this.drilldownFilters = []; } // Initialize layer filters - if (this.drilldownLayers) { - this.drilldownLayers.forEach(layer => { - if (layer.filters) { - layer.filters.forEach((filter: any) => { + if (this.drilldownLayers && Array.isArray(this.drilldownLayers)) { + this.drilldownLayers.forEach((layer, layerIndex) => { + console.log(`Processing drilldown layer ${layerIndex}:`, layer); + if (layer.filters && Array.isArray(layer.filters)) { + layer.filters.forEach((filter, filterIndex) => { + console.log(`Processing layer ${layerIndex} filter ${filterIndex}:`, filter); if (filter.value === undefined || filter.value === null) { switch (filter.type) { case 'multiselect': @@ -206,10 +302,16 @@ export class UnifiedChartComponent implements OnInit, OnChanges, OnDestroy { default: filter.value = ''; } + console.log(`Initialized layer ${layerIndex} filter ${filterIndex} value to:`, filter.value); + } else { + console.log(`Layer ${layerIndex} filter ${filterIndex} already has value:`, filter.value); } }); } }); + } else { + // Initialize as empty array if not provided + this.drilldownLayers = []; } console.log('Filter values initialized:', { @@ -221,6 +323,18 @@ export class UnifiedChartComponent implements OnInit, OnChanges, OnDestroy { // Initialize chart options based on chart type private initializeChartOptions(): void { + // Initialize with default structure to ensure plugins.legend exists + this.chartOptions = { + responsive: true, + maintainAspectRatio: false, + plugins: { + legend: { + display: true, + position: 'top' + } + } + }; + switch (this.chartType) { case 'bar': this.initializeBarChartOptions(); @@ -573,6 +687,11 @@ export class UnifiedChartComponent implements OnInit, OnChanges, OnDestroy { this.isLoading = true; this.noDataAvailable = false; + // Ensure chart options are initialized + if (!this.chartOptions) { + this.initializeChartOptions(); + } + console.log('Starting fetchChartData for chart type:', this.chartType); // If we're in drilldown mode, fetch the appropriate drilldown data @@ -1320,7 +1439,7 @@ export class UnifiedChartComponent implements OnInit, OnChanges, OnDestroy { } public chartHovered(e: any): void { - console.log('Chart hovered:', e); + // console.log('Chart hovered:', e); } // Method to check if chart data is valid @@ -1476,8 +1595,27 @@ export class UnifiedChartComponent implements OnInit, OnChanges, OnDestroy { } // Handle date range changes - onDateRangeChange(filter: any, dateRange: { start: string | null, end: string | null }): void { - filter.value = dateRange; + onDateRangeChange(filter: any, event: any): void { + // For date range filters, we need to handle the change differently + // since we're binding to individual start/end properties + if (!filter.value) { + filter.value = { start: null, end: null }; + } + + // Refresh data when filter changes + this.fetchChartData(); + } + + // Handle date range input changes for start/end dates + onDateRangeInputChange(filter: any, dateType: string, event: any): void { + // Initialize filter.value if it doesn't exist + if (!filter.value) { + filter.value = { start: null, end: null }; + } + + // Update the specific date type (start or end) + filter.value[dateType] = event.target.value; + // Refresh data when filter changes this.fetchChartData(); }