bar chart

This commit is contained in:
string 2025-10-28 17:04:02 +05:30
parent bedcc0822d
commit f740076d60
3 changed files with 383 additions and 214 deletions

View File

@ -1,4 +1,4 @@
<div style="display: block; height: 100%; width: 100%;">
<div class="chart-container">
<!-- Filter Controls Section -->
<div class="filter-section" *ngIf="hasActiveFilters()">
<!-- Base Filters -->
@ -245,6 +245,7 @@
</div>
<!-- Header row with chart title and drilldown navigation -->
<div class="chart-header">
<div class="clr-row header-row">
<div class="clr-col-6">
<h3 class="chart-title">{{charttitle || 'Bar Chart'}}</h3>
@ -278,14 +279,17 @@
</div>
</div>
</div>
</div>
<!-- No data message -->
<div *ngIf="noDataAvailable" style="text-align: center; padding: 20px; color: #666; font-style: italic;">
<div class="chart-wrapper">
<div class="chart-content" [class.loading]="isLoading">
<div *ngIf="noDataAvailable" class="no-data-message">
No data available
</div>
<!-- Chart display -->
<div *ngIf="!noDataAvailable" style="position: relative; height: calc(100% - 50px);">
<div *ngIf="!noDataAvailable" class="chart-display">
<canvas baseChart
[datasets]="barChartData"
[labels]="barChartLabels"
@ -295,4 +299,36 @@
(chartClick)="chartClicked($event)">
</canvas>
</div>
<div class="loading-overlay" *ngIf="isLoading">
<div class="shimmer-bar"></div>
</div>
</div>
</div>
<!-- sheield dashboard -->
<!--
<div class="chart-container">
<div class="chart-header">
<h3>Deal Stage Wise Progress</h3>
</div>
<div class="chart-wrapper">
<div class="chart-content" [class.loading]="isLoading">
<canvas
baseChart
[data]="barChartData"
[options]="barChartOptions"
[type]="barChartType"
(chartClick)="chartClicked($event)"
(chartHover)="chartHovered($event)">
</canvas>
<div class="loading-overlay" *ngIf="isLoading">
<div class="shimmer-bar"></div>
</div>
</div>
</div>
</div> -->
</div>

View File

@ -1,3 +1,10 @@
// Chart container structure
.chart-container {
height: 100%;
display: flex;
flex-direction: column;
// Filter section styling
.filter-section {
margin-bottom: 20px;
padding: 15px;
@ -160,7 +167,10 @@
}
}
// New header row styling
// Chart header styling
.chart-header {
margin-bottom: 20px;
.header-row {
margin-bottom: 15px;
padding-bottom: 10px;
@ -173,9 +183,78 @@
color: #333;
}
}
}
// Chart wrapper and content
.chart-wrapper {
flex: 1;
position: relative;
.chart-content {
position: relative;
height: 100%;
min-height: 300px; // Ensure minimum height for chart
&.loading {
opacity: 0.7;
.chart-display {
filter: blur(2px);
}
}
.no-data-message {
text-align: center;
padding: 20px;
color: #666;
font-style: italic;
}
.chart-display {
position: relative;
height: 100%;
width: 100%;
max-width: 100%;
max-height: 100%;
transition: filter 0.3s ease;
}
.loading-overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: flex;
align-items: center;
justify-content: center;
background: rgba(255, 255, 255, 0.8);
.shimmer-bar {
width: 80%;
height: 20px;
background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
background-size: 200% 100%;
animation: shimmer 1.5s infinite;
border-radius: 4px;
}
}
}
}
}
@keyframes shimmer {
0% {
background-position: -200% 0;
}
100% {
background-position: 200% 0;
}
}
// Responsive design
@media (max-width: 768px) {
.chart-container {
.filter-controls {
flex-direction: column;
}
@ -184,9 +263,16 @@
min-width: 100%;
}
.chart-header {
.header-row {
.chart-title {
font-size: 16px;
}
}
}
.chart-content {
min-height: 250px; // Adjust for mobile
}
}
}

View File

@ -57,21 +57,46 @@ export class BarChartComponent implements OnInit, OnChanges, OnDestroy {
ticks: {
autoSkip: false,
maxRotation: 45,
minRotation: 45
minRotation: 45,
padding: 15,
font: {
size: 12
}
},
grid: {
display: false
}
},
y: {
beginAtZero: true
beginAtZero: true,
ticks: {
font: {
size: 12
}
}
}
},
plugins: {
legend: {
display: true,
position: 'top',
labels: {
font: {
size: 12
}
}
},
tooltip: {
enabled: true
}
},
layout: {
padding: {
bottom: 60,
left: 15,
right: 15,
top: 15
}
}
};
@ -84,6 +109,9 @@ export class BarChartComponent implements OnInit, OnChanges, OnDestroy {
// No data state
noDataAvailable: boolean = false;
// Loading state
isLoading: boolean = false;
// Flag to prevent infinite loops
private isFetchingData: boolean = false;
@ -463,14 +491,18 @@ export class BarChartComponent implements OnInit, OnChanges, OnDestroy {
}
fetchChartData(): void {
// Set loading state
this.isLoading = true;
// Set flag to prevent recursive calls
this.isFetchingData = true;
// If we're in drilldown mode, fetch the appropriate drilldown data
if (this.currentDrilldownLevel > 0 && this.drilldownStack.length > 0) {
this.fetchDrilldownData();
// Reset flag after fetching
// Reset flags after fetching
this.isFetchingData = false;
this.isLoading = false;
return;
}
@ -540,8 +572,9 @@ export class BarChartComponent implements OnInit, OnChanges, OnDestroy {
this.noDataAvailable = true;
this.barChartLabels = [];
this.barChartData = [];
// Reset flag after fetching
// Reset flags after fetching
this.isFetchingData = false;
this.isLoading = false;
return;
}
@ -570,8 +603,9 @@ export class BarChartComponent implements OnInit, OnChanges, OnDestroy {
this.barChartLabels = [];
this.barChartData = [];
}
// Reset flag after fetching
// Reset flags after fetching
this.isFetchingData = false;
this.isLoading = false;
},
(error) => {
console.error('=== BAR CHART ERROR ===');
@ -579,8 +613,9 @@ export class BarChartComponent implements OnInit, OnChanges, OnDestroy {
this.noDataAvailable = true;
this.barChartLabels = [];
this.barChartData = [];
// Reset flag after fetching
// Reset flags after fetching
this.isFetchingData = false;
this.isLoading = false;
// Keep default data in case of error
}
);
@ -592,8 +627,9 @@ export class BarChartComponent implements OnInit, OnChanges, OnDestroy {
this.noDataAvailable = true;
this.barChartLabels = [];
this.barChartData = [];
// Reset flag after fetching
// Reset flags after fetching
this.isFetchingData = false;
this.isLoading = false;
}
}
@ -755,17 +791,23 @@ export class BarChartComponent implements OnInit, OnChanges, OnDestroy {
// Trigger change detection
// this.barChartData = [...this.barChartData];
console.log('Updated bar chart with drilldown data:', { labels: this.barChartLabels, data: this.barChartData });
// Set loading state to false
this.isLoading = false;
} else if (data && data.labels && data.datasets) {
// Backend has already filtered the data, just display it
this.noDataAvailable = data.labels.length === 0;
this.barChartLabels = data.labels;
this.barChartData = data.datasets;
console.log('Updated bar chart with drilldown legacy data format:', { labels: this.barChartLabels, data: this.barChartData });
// Set loading state to false
this.isLoading = false;
} else {
console.warn('Drilldown received data does not have expected structure', data);
this.noDataAvailable = true;
this.barChartLabels = [];
this.barChartData = [];
// Set loading state to false
this.isLoading = false;
}
},
(error) => {
@ -773,12 +815,17 @@ export class BarChartComponent implements OnInit, OnChanges, OnDestroy {
this.noDataAvailable = true;
this.barChartLabels = [];
this.barChartData = [];
// Set loading state to false
this.isLoading = false;
// Keep current data in case of error
}
);
// Add subscription to array for cleanup
this.subscriptions.push(subscription);
// Set loading state
this.isLoading = true;
}
// Reset to original data (go back to base level)