chart
This commit is contained in:
@@ -89,17 +89,25 @@ export class DynamicChartLoaderService {
|
||||
* Get chart type by name
|
||||
* This is useful for finding a chart type by its name rather than ID
|
||||
*/
|
||||
getChartTypeByName(name: string): Observable<ChartType | null> {
|
||||
// getChartTypeByName(name: string): Observable<ChartType | null> {
|
||||
// console.log(`Finding chart type by name: ${name}`);
|
||||
// return this.apiRequest.get(`${this.chartTypesUrl}/byname?chartName=${name}`).pipe(
|
||||
// map((chartTypes: ChartType[]) => {
|
||||
// console.log('Available chart types:', chartTypes);
|
||||
// const chartType = chartTypes.find(ct => ct.name === name);
|
||||
// console.log(`Found chart type for name ${name}:`, chartType);
|
||||
// return chartType || null;
|
||||
// })
|
||||
// );
|
||||
// }
|
||||
|
||||
getChartTypeByName(name: string): Observable<any> {
|
||||
console.log(`Finding chart type by name: ${name}`);
|
||||
return this.apiRequest.get(`${this.chartTypesUrl}`).pipe(
|
||||
map((chartTypes: ChartType[]) => {
|
||||
const chartType = chartTypes.find(ct => ct.name === name);
|
||||
console.log(`Found chart type for name ${name}:`, chartType);
|
||||
return chartType || null;
|
||||
})
|
||||
);
|
||||
return this.apiRequest.get(`${this.chartTypesUrl}/byname?chartName=${name}`);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Load all active chart types
|
||||
* This is used to populate the chart selection in the dashboard editor
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
</div> -->
|
||||
|
||||
<!-- Line Chart -->
|
||||
<div *ngIf="chartType === 'line'" class="chart-canvas-container">
|
||||
<!-- <div *ngIf="chartType === 'line'" class="chart-canvas-container">
|
||||
<canvas baseChart
|
||||
[datasets]="chartData"
|
||||
[labels]="chartLabels"
|
||||
@@ -53,10 +53,10 @@
|
||||
(chartClick)="chartClicked($event)"
|
||||
(chartHover)="chartHovered($event)">
|
||||
</canvas>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<!-- Pie Chart -->
|
||||
<div *ngIf="chartType === 'pie'" class="chart-canvas-container">
|
||||
<!-- <div *ngIf="chartType === 'pie'" class="chart-canvas-container">
|
||||
<canvas baseChart
|
||||
[datasets]="chartData"
|
||||
[labels]="chartLabels"
|
||||
@@ -66,10 +66,10 @@
|
||||
(chartClick)="chartClicked($event)"
|
||||
(chartHover)="chartHovered($event)">
|
||||
</canvas>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<!-- Doughnut Chart -->
|
||||
<div *ngIf="chartType === 'doughnut'" class="chart-canvas-container">
|
||||
<!-- <div *ngIf="chartType === 'doughnut'" class="chart-canvas-container">
|
||||
<canvas baseChart
|
||||
[datasets]="chartData"
|
||||
[labels]="chartLabels"
|
||||
@@ -79,10 +79,10 @@
|
||||
(chartClick)="chartClicked($event)"
|
||||
(chartHover)="chartHovered($event)">
|
||||
</canvas>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<!-- Bubble Chart -->
|
||||
<div *ngIf="chartType === 'bubble'" class="chart-canvas-container">
|
||||
<!-- <div *ngIf="chartType === 'bubble'" class="chart-canvas-container">
|
||||
<canvas baseChart
|
||||
[datasets]="bubbleChartData"
|
||||
[options]="chartOptions"
|
||||
@@ -91,10 +91,10 @@
|
||||
(chartClick)="chartClicked($event)"
|
||||
(chartHover)="chartHovered($event)">
|
||||
</canvas>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<!-- Radar Chart -->
|
||||
<div *ngIf="chartType === 'radar'" class="chart-canvas-container">
|
||||
<!-- <div *ngIf="chartType === 'radar'" class="chart-canvas-container">
|
||||
<canvas baseChart
|
||||
[datasets]="chartData"
|
||||
[labels]="chartLabels"
|
||||
@@ -104,10 +104,10 @@
|
||||
(chartClick)="chartClicked($event)"
|
||||
(chartHover)="chartHovered($event)">
|
||||
</canvas>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<!-- Polar Area Chart -->
|
||||
<div *ngIf="chartType === 'polar'" class="chart-canvas-container">
|
||||
<!-- <div *ngIf="chartType === 'polar'" class="chart-canvas-container">
|
||||
<canvas baseChart
|
||||
[datasets]="chartData"
|
||||
[labels]="chartLabels"
|
||||
@@ -117,10 +117,10 @@
|
||||
(chartClick)="chartClicked($event)"
|
||||
(chartHover)="chartHovered($event)">
|
||||
</canvas>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<!-- Scatter Chart -->
|
||||
<div *ngIf="chartType === 'scatter'" class="chart-canvas-container">
|
||||
<!-- <div *ngIf="chartType === 'scatter'" class="chart-canvas-container">
|
||||
<canvas baseChart
|
||||
[datasets]="chartData"
|
||||
[options]="chartOptions"
|
||||
@@ -129,7 +129,7 @@
|
||||
(chartClick)="chartClicked($event)"
|
||||
(chartHover)="chartHovered($event)">
|
||||
</canvas>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<!-- Default/Unknown Chart Type -->
|
||||
<div *ngIf="!['bar', 'line', 'pie', 'doughnut', 'bubble', 'radar', 'polar', 'scatter'].includes(chartType)" class="chart-canvas-container">
|
||||
|
||||
@@ -81,6 +81,12 @@ export class UnifiedChartComponent implements OnInit, OnChanges, OnDestroy {
|
||||
dynamicStyles: string = '';
|
||||
dynamicOptions: any = null;
|
||||
|
||||
// Add setter to log when dynamicTemplate changes
|
||||
setDynamicTemplate(value: string) {
|
||||
console.log('Setting dynamic template:', value);
|
||||
this.dynamicTemplate = value;
|
||||
}
|
||||
|
||||
constructor(
|
||||
private dashboardService: Dashboard3Service,
|
||||
private filterService: FilterService,
|
||||
@@ -129,6 +135,11 @@ export class UnifiedChartComponent implements OnInit, OnChanges, OnDestroy {
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
console.log('UnifiedChartComponent input changes:', changes);
|
||||
|
||||
// Log chartType changes specifically
|
||||
if (changes.chartType) {
|
||||
console.log('Chart type changed from', changes.chartType.previousValue, 'to', changes.chartType.currentValue);
|
||||
}
|
||||
|
||||
// Log all input values for debugging
|
||||
console.log('Current input values:', {
|
||||
chartType: this.chartType,
|
||||
@@ -199,8 +210,8 @@ export class UnifiedChartComponent implements OnInit, OnChanges, OnDestroy {
|
||||
|
||||
// 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 ||
|
||||
drilldownLayersChanged)) {
|
||||
drilldownEnabledChanged || drilldownApiUrlChanged || drilldownXAxisChanged || drilldownYAxisChanged ||
|
||||
drilldownLayersChanged)) {
|
||||
console.log('Chart configuration changed, fetching new data');
|
||||
this.initializeChartOptions();
|
||||
this.fetchChartData();
|
||||
@@ -243,38 +254,53 @@ export class UnifiedChartComponent implements OnInit, OnChanges, OnDestroy {
|
||||
}
|
||||
|
||||
console.log(`Loading dynamic chart configuration for chart type: ${this.chartType}`);
|
||||
console.log('Current dynamic template:', this.dynamicTemplate);
|
||||
|
||||
// Get chart type by name and load its configuration
|
||||
console.log('Calling getChartTypeByName with:', this.chartType);
|
||||
this.dynamicChartLoader.getChartTypeByName(this.chartType).subscribe({
|
||||
next: (chartType) => {
|
||||
console.log('Received chart type by name :', chartType);
|
||||
if (chartType) {
|
||||
console.log('Found chart type:', chartType);
|
||||
|
||||
// Load the complete configuration for this chart type
|
||||
console.log('Loading chart configuration for chart type ID:', chartType.id);
|
||||
this.dynamicChartLoader.loadChartConfiguration(chartType.id).subscribe({
|
||||
next: (config) => {
|
||||
console.log('Received chart configuration:', config);
|
||||
console.log('Loaded chart configuration:', config);
|
||||
|
||||
// Apply the first template if available
|
||||
if (config.templates && config.templates.length > 0) {
|
||||
const defaultTemplate = config.templates.find(t => t.isDefault) || config.templates[0];
|
||||
if (defaultTemplate) {
|
||||
this.dynamicTemplate = defaultTemplate.templateHtml || '';
|
||||
this.setDynamicTemplate(defaultTemplate.templateHtml || '');
|
||||
this.dynamicStyles = defaultTemplate.templateCss || '';
|
||||
|
||||
// Apply styles to the component
|
||||
this.applyDynamicStyles();
|
||||
|
||||
console.log('Applied dynamic template and styles');
|
||||
console.log('Applied dynamic template and styles', {
|
||||
template: this.dynamicTemplate,
|
||||
styles: this.dynamicStyles
|
||||
});
|
||||
}
|
||||
} else {
|
||||
console.log('No templates found for chart type:', this.chartType);
|
||||
}
|
||||
|
||||
// Apply dynamic options if available
|
||||
console.log('Checking for dynamic fields:', config.dynamicFields);
|
||||
if (config.dynamicFields && config.dynamicFields.length > 0) {
|
||||
// Find the field that contains chart options
|
||||
const optionsField = config.dynamicFields.find(field =>
|
||||
field.fieldName === 'chartOptions' || field.fieldName.toLowerCase().includes('options'));
|
||||
|
||||
if (!optionsField) {
|
||||
console.log('No chartOptions field found in dynamic fields');
|
||||
}
|
||||
|
||||
if (optionsField && optionsField.fieldOptions) {
|
||||
try {
|
||||
this.dynamicOptions = JSON.parse(optionsField.fieldOptions);
|
||||
@@ -286,6 +312,8 @@ export class UnifiedChartComponent implements OnInit, OnChanges, OnDestroy {
|
||||
console.error('Error parsing dynamic chart options:', e);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.log('No dynamic fields found for chart type:', this.chartType);
|
||||
}
|
||||
},
|
||||
error: (error) => {
|
||||
@@ -294,6 +322,16 @@ export class UnifiedChartComponent implements OnInit, OnChanges, OnDestroy {
|
||||
});
|
||||
} else {
|
||||
console.log(`Chart type ${this.chartType} not found in database`);
|
||||
// Log available chart types for debugging
|
||||
console.log('Available chart types in database:');
|
||||
this.dynamicChartLoader.loadAllChartConfigurations().subscribe({
|
||||
next: (chartTypes) => {
|
||||
console.log('All chart types:', chartTypes);
|
||||
},
|
||||
error: (error) => {
|
||||
console.error('Error loading chart types:', error);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
error: (error) => {
|
||||
@@ -713,7 +751,7 @@ export class UnifiedChartComponent implements OnInit, OnChanges, OnDestroy {
|
||||
mode: 'point',
|
||||
intersect: false,
|
||||
callbacks: {
|
||||
label: function(context: any) {
|
||||
label: function (context: any) {
|
||||
const point: any = context.raw;
|
||||
if (point && point.hasOwnProperty('y') && point.hasOwnProperty('r')) {
|
||||
const yValue = parseFloat(point.y);
|
||||
@@ -1216,8 +1254,8 @@ export class UnifiedChartComponent implements OnInit, OnChanges, OnDestroy {
|
||||
|
||||
// If we have the expected bubble data format, return it as is
|
||||
if (data && data.length > 0 && data[0].data && data[0].data.length > 0 &&
|
||||
typeof data[0].data[0] === 'object' && data[0].data[0].hasOwnProperty('x') &&
|
||||
data[0].data[0].hasOwnProperty('y') && data[0].data[0].hasOwnProperty('r')) {
|
||||
typeof data[0].data[0] === 'object' && data[0].data[0].hasOwnProperty('x') &&
|
||||
data[0].data[0].hasOwnProperty('y') && data[0].data[0].hasOwnProperty('r')) {
|
||||
console.log('Data is already in bubble format, returning as is');
|
||||
return data;
|
||||
}
|
||||
@@ -1399,17 +1437,17 @@ export class UnifiedChartComponent implements OnInit, OnChanges, OnDestroy {
|
||||
const hue2rgb = (p: number, q: number, t: number) => {
|
||||
if (t < 0) t += 1;
|
||||
if (t > 1) t -= 1;
|
||||
if (t < 1/6) return p + (q - p) * 6 * t;
|
||||
if (t < 1/2) return q;
|
||||
if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
|
||||
if (t < 1 / 6) return p + (q - p) * 6 * t;
|
||||
if (t < 1 / 2) return q;
|
||||
if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
|
||||
return p;
|
||||
};
|
||||
|
||||
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
||||
const p = 2 * l - q;
|
||||
r = hue2rgb(p, q, h + 1/3);
|
||||
r = hue2rgb(p, q, h + 1 / 3);
|
||||
g = hue2rgb(p, q, h);
|
||||
b = hue2rgb(p, q, h - 1/3);
|
||||
b = hue2rgb(p, q, h - 1 / 3);
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -1534,9 +1572,9 @@ export class UnifiedChartComponent implements OnInit, OnChanges, OnDestroy {
|
||||
if (layerIndex < this.drilldownLayers.length) {
|
||||
drilldownConfig = this.drilldownLayers[layerIndex];
|
||||
hasDrilldownConfig = drilldownConfig.enabled &&
|
||||
!!drilldownConfig.apiUrl &&
|
||||
!!drilldownConfig.xAxis &&
|
||||
!!drilldownConfig.yAxis;
|
||||
!!drilldownConfig.apiUrl &&
|
||||
!!drilldownConfig.xAxis &&
|
||||
!!drilldownConfig.yAxis;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1634,8 +1672,8 @@ export class UnifiedChartComponent implements OnInit, OnChanges, OnDestroy {
|
||||
// Check if there are active filters
|
||||
hasActiveFilters(): boolean {
|
||||
return (this.baseFilters && this.baseFilters.length > 0) ||
|
||||
(this.drilldownFilters && this.drilldownFilters.length > 0) ||
|
||||
this.hasActiveLayerFilters();
|
||||
(this.drilldownFilters && this.drilldownFilters.length > 0) ||
|
||||
this.hasActiveLayerFilters();
|
||||
}
|
||||
|
||||
// Check if there are active layer filters for current drilldown level
|
||||
@@ -1643,8 +1681,8 @@ export class UnifiedChartComponent implements OnInit, OnChanges, OnDestroy {
|
||||
if (this.currentDrilldownLevel > 1 && this.drilldownLayers && this.drilldownLayers.length > 0) {
|
||||
const layerIndex = this.currentDrilldownLevel - 2; // -2 because level 1 is base drilldown
|
||||
return layerIndex < this.drilldownLayers.length &&
|
||||
this.drilldownLayers[layerIndex].filters &&
|
||||
this.drilldownLayers[layerIndex].filters.length > 0;
|
||||
this.drilldownLayers[layerIndex].filters &&
|
||||
this.drilldownLayers[layerIndex].filters.length > 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -1654,7 +1692,7 @@ export class UnifiedChartComponent implements OnInit, OnChanges, OnDestroy {
|
||||
if (this.currentDrilldownLevel > 1 && this.drilldownLayers && this.drilldownLayers.length > 0) {
|
||||
const layerIndex = this.currentDrilldownLevel - 2; // -2 because level 1 is base drilldown
|
||||
if (layerIndex < this.drilldownLayers.length &&
|
||||
this.drilldownLayers[layerIndex].filters) {
|
||||
this.drilldownLayers[layerIndex].filters) {
|
||||
return this.drilldownLayers[layerIndex].filters;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user