Commit ee3aaf4c by Ooh-Ao

config

parent b85fa99d
import { Component, OnInit, Type, ChangeDetectionStrategy } from '@angular/core'; // Import Type
import { CommonModule } from '@angular/common';
import { ActivatedRoute, RouterModule } from '@angular/router';
......@@ -43,7 +42,7 @@ import { SlicerWidgetComponent } from '../widgets/slicer-widget/slicer-widget.co
import { SimpleTableWidgetComponent } from '../widgets/simple-table-widget/simple-table-widget.component';
import { WaterfallChartWidgetComponent } from '../widgets/waterfall-chart-widget/waterfall-chart-widget.component';
import { TreemapWidgetComponent } from '../widgets/treemap-widget/treemap-widget.component';
import { SharedModule } from '../../shared/shared.module';
import { HttpClientModule } from '@angular/common/http';
@Component({
......@@ -54,7 +53,7 @@ import { SharedModule } from '../../shared/shared.module';
RouterModule,
DashboardLayoutModule,
NgComponentOutlet,
SharedModule,
HttpClientModule,
SyncfusionDatagridWidgetComponent,
SyncfusionPivotWidgetComponent,
SyncfusionChartWidgetComponent,
......@@ -171,12 +170,13 @@ export class DashboardViewerComponent implements OnInit {
forkJoin(dataFetchTasks).subscribe(() => {
console.log('All widget data fetched for viewer.');
this.panels = dashboard.widgets.map(widget => {
console.log(`Mapping widget: ${widget.name}, Component: ${widget.component}, Resolved Type: ${this.widgetComponentMap[widget.component]}`);
let inputs = {};
if (widget.component === 'NewDataTableWidget') {
inputs = { config: widget.config };
} else {
inputs = { ...widget.data, datasetId: dashboard.datasetId };
// Always pass the entire widget.config as the input to the component
// Ensure widget.config exists, initialize if not.
const widgetConfig = widget.config || {};
// Add datasetId to the config if it exists in the dashboardData
if (dashboard.datasetId) {
widgetConfig.datasetId = dashboard.datasetId;
}
return {
......@@ -188,19 +188,20 @@ export class DashboardViewerComponent implements OnInit {
header: widget.name,
componentName: widget.component, // Add componentName
componentType: this.widgetComponentMap[widget.component], // Attach the component Type
componentInputs: inputs // Pass inputs
componentInputs: { config: widgetConfig } // Pass the config object as 'config' input
};
});
});
} else {
// No data to fetch, directly map panels
this.panels = dashboard.widgets.map(widget => {
console.log(`Mapping widget: ${widget.name}, Component: ${widget.component}, Resolved Type: ${this.widgetComponentMap[widget.component]}`);
let inputs = {};
if (widget.component === 'NewDataTableWidget') {
inputs = { config: widget.config };
} else {
inputs = { ...widget.data, datasetId: dashboard.datasetId };
// Always pass the entire widget.config as the input to the component
// Ensure widget.config exists, initialize if not.
const widgetConfig = widget.config || {};
// Add datasetId to the config if it exists in the dashboardData
if (dashboard.datasetId) {
widgetConfig.datasetId = dashboard.datasetId;
}
return {
......@@ -212,7 +213,7 @@ export class DashboardViewerComponent implements OnInit {
header: widget.name,
componentName: widget.component, // Add componentName
componentType: this.widgetComponentMap[widget.component], // Attach the component Type
componentInputs: inputs // Pass inputs
componentInputs: { config: widgetConfig } // Pass the config object as 'config' input
};
});
}
......
<ejs-chart [title]="title" [primaryXAxis]="primaryXAxis" [primaryYAxis]="primaryYAxis">
<e-series-collection>
<e-series [dataSource]="chartData" type="Area" xName="month" yName="sales" name="Sales"></e-series>
<e-series [dataSource]="chartData" type="Area" xName="x" yName="y" name="Sales"></e-series>
</e-series-collection>
</ejs-chart>
import { Component, Input, OnInit } from '@angular/core';
import { Component, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ChartModule, AreaSeriesService, CategoryService, LegendService, TooltipService, DataLabelService } from '@syncfusion/ej2-angular-charts';
import { HttpClient, HttpClientModule } from '@angular/common/http';
import { DatasetService } from '../../services/dataset.service';
import { DatasetModel } from '../../models/widgets.model';
@Component({
selector: 'app-area-chart-widget',
standalone: true,
imports: [CommonModule, ChartModule],
providers: [AreaSeriesService, CategoryService, LegendService, TooltipService, DataLabelService],
imports: [CommonModule, ChartModule, HttpClientModule],
providers: [AreaSeriesService, CategoryService, LegendService, TooltipService, DataLabelService, DatasetService, HttpClient],
templateUrl: './area-chart-widget.component.html',
})
export class AreaChartWidgetComponent implements OnInit {
@Input() chartData: Object[];
@Input() title: string = 'Area Chart';
export class AreaChartWidgetComponent implements OnInit, OnChanges {
@Input() config: any;
public chartData: Object[];
public title: string = 'Area Chart';
public primaryXAxis: Object;
public primaryYAxis: Object;
constructor(private datasetService: DatasetService, private http: HttpClient) { }
ngOnInit(): void {
this.primaryXAxis = { valueType: 'Category', title: 'Month' };
this.primaryYAxis = { title: 'Sales' };
if (!this.chartData) {
// Default data if no config is provided
if (!this.config || !this.config.datasetId) {
this.chartData = [
{ month: 'Jan', sales: 35 }, { month: 'Feb', sales: 28 },
{ month: 'Mar', sales: 34 }, { month: 'Apr', sales: 32 },
......@@ -27,4 +35,40 @@ export class AreaChartWidgetComponent implements OnInit {
];
}
}
ngOnChanges(changes: SimpleChanges): void {
if (changes['config'] && this.config && this.config.datasetId) {
this.loadData();
} else if (changes['config'] && (!this.config || !this.config.datasetId)) {
// Reset to default data if config or datasetId is removed
this.chartData = [
{ month: 'Jan', sales: 35 }, { month: 'Feb', sales: 28 },
{ month: 'Mar', sales: 34 }, { month: 'Apr', sales: 32 },
{ month: 'May', sales: 40 }, { month: 'Jun', sales: 30 },
];
}
}
loadData(): void {
if (this.config.datasetId) {
this.datasetService.getDatasetById(this.config.datasetId).subscribe((dataset: DatasetModel | undefined) => {
if (dataset && dataset.url) {
this.http.get<any[]>(dataset.url).subscribe(data => {
// Assuming the data fetched is directly usable by the chart
// You might need to transform the data based on config.xField, config.yField
this.chartData = data.map(item => ({ x: item[this.config.xField], y: item[this.config.yField] }));
if (this.config.title) {
this.title = this.config.title;
}
if (this.config.xAxisTitle) {
this.primaryXAxis = { ...this.primaryXAxis, title: this.config.xAxisTitle, valueType: 'Category' };
}
if (this.config.yAxisTitle) {
this.primaryYAxis = { ...this.primaryYAxis, title: this.config.yAxisTitle };
}
});
}
});
}
}
}
<ejs-chart [title]="title" [primaryXAxis]="primaryXAxis" [primaryYAxis]="primaryYAxis">
<e-series-collection>
<e-series [dataSource]="chartData" [type]="type" xName="country" yName="sales" name="Sales"></e-series>
<e-series [dataSource]="chartData" [type]="type" xName="x" yName="y" name="Data"></e-series>
</e-series-collection>
</ejs-chart>
import { Component, Input, OnInit } from '@angular/core';
import { Component, Input, OnInit, OnChanges, SimpleChanges } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ChartModule, BarSeriesService, ColumnSeriesService, CategoryService, LegendService, TooltipService, DataLabelService } from '@syncfusion/ej2-angular-charts';
import { HttpClient, HttpClientModule } from '@angular/common/http';
import { DatasetService } from '../../services/dataset.service';
import { DatasetModel } from '../../models/widgets.model';
@Component({
selector: 'app-bar-chart-widget',
standalone: true,
imports: [CommonModule, ChartModule],
providers: [BarSeriesService, ColumnSeriesService, CategoryService, LegendService, TooltipService, DataLabelService],
imports: [CommonModule, ChartModule, HttpClientModule],
providers: [BarSeriesService, ColumnSeriesService, CategoryService, LegendService, TooltipService, DataLabelService, DatasetService, HttpClient],
templateUrl: './bar-chart-widget.component.html',
})
export class BarChartWidgetComponent implements OnInit {
@Input() config: any;
@Input() chartData: Object[];
@Input() title: string = 'Bar Chart';
@Input() type: 'Bar' | 'Column' = 'Column';
......@@ -17,10 +21,12 @@ export class BarChartWidgetComponent implements OnInit {
public primaryXAxis: Object;
public primaryYAxis: Object;
constructor(private datasetService: DatasetService, private http: HttpClient) { }
ngOnInit(): void {
this.primaryXAxis = { valueType: 'Category', title: 'Country' };
this.primaryYAxis = { title: 'Sales' };
if (!this.chartData) {
if (!this.config || !this.config.datasetId) {
this.chartData = [
{ country: 'USA', sales: 20 },
{ country: 'China', sales: 25 },
......@@ -29,4 +35,41 @@ export class BarChartWidgetComponent implements OnInit {
];
}
}
ngOnChanges(changes: SimpleChanges): void {
if (changes['config'] && this.config && this.config.datasetId) {
this.loadData();
} else if (changes['config'] && (!this.config || !this.config.datasetId)) {
this.chartData = [
{ country: 'USA', sales: 20 },
{ country: 'China', sales: 25 },
{ country: 'Japan', sales: 18 },
{ country: 'Germany', sales: 15 },
];
}
}
loadData(): void {
if (this.config.datasetId) {
this.datasetService.getDatasetById(this.config.datasetId).subscribe((dataset: DatasetModel | undefined) => {
if (dataset && dataset.url) {
this.http.get<any[]>(dataset.url).subscribe(data => {
this.chartData = data.map(item => ({ x: item[this.config.xField], y: item[this.config.yField] }));
if (this.config.title) {
this.title = this.config.title;
}
if (this.config.xAxisTitle) {
this.primaryXAxis = { ...this.primaryXAxis, title: this.config.xAxisTitle };
}
if (this.config.yAxisTitle) {
this.primaryYAxis = { ...this.primaryYAxis, title: this.config.yAxisTitle };
}
if (this.config.type) {
this.type = this.config.type;
}
});
}
});
}
}
}
<div class="bg-white p-6 rounded-lg shadow-md h-full flex flex-col">
<h3 class="text-lg font-semibold text-gray-500 mb-4">Monthly Activity</h3>
<div id="chart" #chart class="flex-grow"></div>
<div #chart class="h-full w-full"></div>
</div>
import { Component, OnInit, ViewChild, ElementRef, AfterViewInit, Input } from '@angular/core';
import { Component, OnInit, ViewChild, ElementRef, AfterViewInit, Input, SimpleChanges, OnChanges } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MockDataService } from '../../common/mock-data.service';
import { DatasetModel } from '../../models/widgets.model';
import { DatasetService } from '../../services/dataset.service';
import { HttpClient } from '@angular/common/http';
// Declare ApexCharts globally if it's loaded via a script tag
declare var ApexCharts: any;
......@@ -11,20 +14,19 @@ declare var ApexCharts: any;
imports: [CommonModule],
templateUrl: './chart-widget.component.html',
})
export class ChartWidgetComponent implements OnInit, AfterViewInit {
export class ChartWidgetComponent implements OnInit, AfterViewInit, OnChanges {
@ViewChild('chart') chartElement!: ElementRef;
@Input() title: string = 'Chart'; // New input for title
@Input() chartData: { categories: string[], series: { name: string, data: number[] }[] } | undefined; // New input for chart data
@Input() config: any;
chartOptions: any;
private chartInstance: any; // To store the ApexCharts instance
constructor(private mockDataService: MockDataService) { }
constructor(private datasetService: DatasetService, private http: HttpClient) { }
ngOnInit(): void {
const dataToUse = this.chartData || this.mockDataService.getChartData();
// Initial chart options, will be updated with fetched data
this.chartOptions = {
series: dataToUse.series,
series: [],
chart: {
type: 'bar',
height: 250,
......@@ -48,7 +50,7 @@ export class ChartWidgetComponent implements OnInit, AfterViewInit {
colors: ['transparent']
},
xaxis: {
categories: dataToUse.categories,
categories: [],
},
yaxis: {
title: {
......@@ -68,12 +70,65 @@ export class ChartWidgetComponent implements OnInit, AfterViewInit {
};
}
ngOnChanges(changes: SimpleChanges): void {
if (changes['config'] && this.config && this.config.datasetId) {
this.loadData();
} else if (changes['config'] && (!this.config || !this.config.datasetId)) {
// Reset chart if config or datasetId is removed
this.chartOptions.series = [];
this.chartOptions.xaxis.categories = [];
if (this.chartInstance) {
this.chartInstance.updateOptions(this.chartOptions);
}
}
}
ngAfterViewInit(): void {
if (typeof ApexCharts !== 'undefined') {
const chart = new ApexCharts(this.chartElement.nativeElement, this.chartOptions);
chart.render();
if (typeof ApexCharts !== 'undefined' && this.chartElement) {
this.chartInstance = new ApexCharts(this.chartElement.nativeElement, this.chartOptions);
this.chartInstance.render();
} else {
console.error('ApexCharts is not loaded.');
console.error('ApexCharts is not loaded or chart element is not available.');
}
}
loadData(): void {
if (this.config.datasetId) {
this.datasetService.getDatasetById(this.config.datasetId).subscribe((dataset: DatasetModel | undefined) => {
if (dataset && dataset.url) {
this.http.get<any[]>(dataset.url).subscribe(data => {
// Transform data for ApexCharts
// Assuming config.xField for categories and config.yFields for series
const categories = data.map(item => item[this.config.xField]);
const series = this.config.yFields.map((yField: any) => ({
name: yField.name || yField.field,
data: data.map(item => item[yField.field])
}));
const newOptions = {
series: series,
xaxis: {
categories: categories,
},
title: {
text: this.config.title || 'Chart'
},
yaxis: {
title: {
text: this.config.yAxisTitle || 'Number'
}
}
};
if (this.chartInstance) {
this.chartInstance.updateOptions(newOptions);
} else {
// If chartInstance is not yet created (e.g., first load), update chartOptions directly
this.chartOptions = { ...this.chartOptions, ...newOptions };
}
});
}
});
}
}
}
<ejs-chart [title]="title" [primaryXAxis]="primaryXAxis" [primaryYAxis]="primaryYAxis">
<e-series-collection>
<e-series [dataSource]="chartData" type="Column" xName="month" yName="sales" name="Sales"></e-series>
<e-series [dataSource]="chartData" type="Line" xName="month" yName="profit" name="Profit"></e-series>
<e-series *ngFor="let yField of config.yFields" [dataSource]="chartData" [type]="yField.type || 'Column'" xName="x" [yName]="yField.field" [name]="yField.name"></e-series>
</e-series-collection>
</ejs-chart>
import { Component, Input, OnInit } from '@angular/core';
import { Component, Input, OnInit, OnChanges, SimpleChanges } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ChartModule, ColumnSeriesService, LineSeriesService, CategoryService, LegendService, TooltipService, DataLabelService } from '@syncfusion/ej2-angular-charts';
import { DatasetService } from '../../services/dataset.service';
import { HttpClient, HttpClientModule } from '@angular/common/http';
import { DatasetModel } from '../../models/widgets.model';
@Component({
selector: 'app-combo-chart-widget',
standalone: true,
imports: [CommonModule, ChartModule],
providers: [ColumnSeriesService, LineSeriesService, CategoryService, LegendService, TooltipService, DataLabelService],
imports: [CommonModule, ChartModule, HttpClientModule],
providers: [ColumnSeriesService, LineSeriesService, CategoryService, LegendService, TooltipService, DataLabelService, DatasetService, HttpClient],
templateUrl: './combo-chart-widget.component.html',
})
export class ComboChartWidgetComponent implements OnInit {
export class ComboChartWidgetComponent implements OnInit, OnChanges {
@Input() config: any;
@Input() chartData: Object[];
@Input() title: string = 'Combo Chart';
public primaryXAxis: Object;
public primaryYAxis: Object;
constructor(private datasetService: DatasetService, private http: HttpClient) { }
ngOnInit(): void {
this.primaryXAxis = { valueType: 'Category', title: 'Month' };
this.primaryYAxis = { title: 'Value' };
if (!this.chartData) {
if (!this.config || !this.config.datasetId) {
this.chartData = [
{ month: 'Jan', sales: 35, profit: 10 }, { month: 'Feb', sales: 28, profit: 12 },
{ month: 'Mar', sales: 34, profit: 8 }, { month: 'Apr', sales: 32, profit: 15 },
......@@ -27,4 +33,46 @@ export class ComboChartWidgetComponent implements OnInit {
];
}
}
ngOnChanges(changes: SimpleChanges): void {
if (changes['config'] && this.config && this.config.datasetId) {
this.loadData();
} else if (changes['config'] && (!this.config || !this.config.datasetId)) {
this.chartData = [
{ month: 'Jan', sales: 35, profit: 10 }, { month: 'Feb', sales: 28, profit: 12 },
{ month: 'Mar', sales: 34, profit: 8 }, { month: 'Apr', sales: 32, profit: 15 },
{ month: 'May', sales: 40, profit: 11 }, { month: 'Jun', sales: 30, profit: 13 },
];
}
}
loadData(): void {
if (this.config.datasetId) {
this.datasetService.getDatasetById(this.config.datasetId).subscribe((dataset: DatasetModel | undefined) => {
if (dataset && dataset.url) {
this.http.get<any[]>(dataset.url).subscribe(data => {
// Transform data for combo chart
// Assuming config.xField and config.yFields (array of y-fields)
this.chartData = data.map(item => {
const transformedItem: any = { x: item[this.config.xField] };
this.config.yFields.forEach((field: string) => {
transformedItem[field] = item[field];
});
return transformedItem;
});
if (this.config.title) {
this.title = this.config.title;
}
if (this.config.xAxisTitle) {
this.primaryXAxis = { ...this.primaryXAxis, title: this.config.xAxisTitle };
}
if (this.config.yAxisTitle) {
this.primaryYAxis = { ...this.primaryYAxis, title: this.config.yAxisTitle };
}
});
}
});
}
}
}
import { Component, Input, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-company-info-widget',
standalone: true,
imports: [CommonModule],
templateUrl: './company-info-widget.component.html',
styleUrls: ['./company-info-widget.component.scss']
})
......
<ejs-accumulationchart [title]="title" [legendSettings]="legendSettings" [enableSmartLabels]="true">
<e-accumulation-series-collection>
<e-accumulation-series [dataSource]="chartData" type="Doughnut" xName="browser" yName="users" [dataLabel]="{ visible: true, name: 'text', position: 'Inside' }" innerRadius="40%"></e-accumulation-series>
<e-accumulation-series [dataSource]="chartData" type="Doughnut" xName="x" yName="y" [dataLabel]="{ visible: true, name: 'text', position: 'Inside' }" innerRadius="40%"></e-accumulation-series>
</e-accumulation-series-collection>
</ejs-accumulationchart>
import { Component, Input, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common';
import { AccumulationChartModule, AccumulationDataLabelService, AccumulationLegendService, AccumulationTooltipService } from '@syncfusion/ej2-angular-charts';
import { DatasetService } from '../../services/dataset.service';
import { HttpClient, HttpClientModule } from '@angular/common/http';
@Component({
selector: 'app-doughnut-chart-widget',
standalone: true,
imports: [CommonModule, AccumulationChartModule],
providers: [ AccumulationDataLabelService, AccumulationLegendService, AccumulationTooltipService],
imports: [CommonModule, AccumulationChartModule, HttpClientModule],
providers: [AccumulationDataLabelService, AccumulationLegendService, AccumulationTooltipService, DatasetService, HttpClient],
templateUrl: './doughnut-chart-widget.component.html',
})
export class DoughnutChartWidgetComponent implements OnInit {
@Input() chartData: Object[];
@Input() title: string = 'Doughnut Chart';
@Input() legendSettings: Object;
@Input() config: any;
constructor(private datasetService: DatasetService, private http: HttpClient) { }
ngOnInit(): void {
if (!this.chartData) {
......
<div class="card h-100">
<div class="card-header">
<h5 class="card-title">Employee Directory</h5>
</div>
<div class="card-body">
<p>This is a placeholder for the employee directory.</p>
<p *ngIf="data">Data received: {{ data | json }}</p>
</div>
</div>
/* Add any specific styles for the employee directory widget here */
.card {
border-radius: 10px;
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
}
import { Component, Input, OnInit } from '@angular/core';
@Component({
selector: 'app-employee-directory-widget',
templateUrl: './employee-directory-widget.component.html',
styleUrls: ['./employee-directory-widget.component.scss']
})
export class EmployeeDirectoryWidgetComponent implements OnInit {
@Input() data: any;
constructor() { }
ngOnInit(): void {
}
}
import { Component, Input, OnInit } from '@angular/core';
import { Component, Input, OnInit, SimpleChanges } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MapsModule, MarkerService, ZoomService, DataLabelService, LegendService, MapsTooltipService } from '@syncfusion/ej2-angular-maps';
import { DatasetModel } from '../../models/widgets.model';
import { DatasetService } from '../../services/dataset.service';
import { HttpClient } from '@angular/common/http';
@Component({
selector: 'app-filled-map-widget',
......@@ -10,15 +13,18 @@ import { MapsModule, MarkerService, ZoomService, DataLabelService, LegendService
templateUrl: './filled-map-widget.component.html',
})
export class FilledMapWidgetComponent implements OnInit {
@Input() config: any;
@Input() title: string = 'Filled Map';
@Input() mapData: Object[];
public zoomSettings: Object;
public layers: Object[];
constructor(private datasetService: DatasetService, private http: HttpClient) { }
ngOnInit(): void {
this.zoomSettings = { enable: true };
if (!this.mapData) {
if (!this.config || !this.config.datasetId) {
this.mapData = [
{ country: 'United States', value: 80 },
{ country: 'Canada', value: 60 },
......@@ -45,4 +51,57 @@ export class FilledMapWidgetComponent implements OnInit {
}
];
}
ngOnChanges(changes: SimpleChanges): void {
if (changes['config'] && this.config && this.config.datasetId) {
this.loadData();
} else if (changes['config'] && (!this.config || !this.config.datasetId)) {
this.mapData = [
{ country: 'United States', value: 80 },
{ country: 'Canada', value: 60 },
{ country: 'Mexico', value: 40 },
];
this.updateLayers();
}
}
loadData(): void {
if (this.config.datasetId) {
this.datasetService.getDatasetById(this.config.datasetId).subscribe((dataset: DatasetModel | undefined) => {
if (dataset && dataset.url) {
this.http.get<any[]>(dataset.url).subscribe(data => {
this.mapData = data.map(item => ({
country: item[this.config.countryField],
value: item[this.config.valueField]
}));
if (this.config.title) {
this.title = this.config.title;
}
this.updateLayers();
});
}
});
}
}
updateLayers(): void {
this.layers = [
{
shapeData: new Object({ data: 'https://cdn.syncfusion.com/maps/map-data/world-map.json' }),
shapeDataPath: 'name',
shapePropertyPath: 'name',
dataSource: this.mapData,
tooltipSettings: { visible: true, valuePath: 'value' },
shapeSettings: {
fill: '#E5EEF6',
colorValuePath: 'value',
colorMapping: [
{ value: 0, color: '#C3E6CB' },
{ value: 50, color: '#FFECB5' },
{ value: 100, color: '#F5C6CB' }
]
}
}
];
}
}
import { Component, Input, OnInit } from '@angular/core';
import { Component, Input, OnInit, SimpleChanges } from '@angular/core';
import { CommonModule } from '@angular/common';
import { AccumulationChartModule, FunnelSeriesService, AccumulationDataLabelService, AccumulationLegendService, AccumulationTooltipService } from '@syncfusion/ej2-angular-charts';
import { DatasetService } from '../../services/dataset.service';
import { HttpClient } from '@angular/common/http';
import { DatasetModel } from '../../models/widgets.model';
@Component({
selector: 'app-funnel-chart-widget',
......@@ -10,12 +13,13 @@ import { AccumulationChartModule, FunnelSeriesService, AccumulationDataLabelServ
templateUrl: './funnel-chart-widget.component.html',
})
export class FunnelChartWidgetComponent implements OnInit {
@Input() config: any;
@Input() chartData: Object[];
@Input() title: string = 'Funnel Chart';
@Input() legendSettings: Object;
constructor(private datasetService: DatasetService, private http: HttpClient) { }
ngOnInit(): void {
if (!this.chartData) {
if (!this.config || !this.config.datasetId) {
this.chartData = [
{ x: 'Website Visitors', y: 10000 },
{ x: 'Leads', y: 8000 },
......@@ -25,4 +29,32 @@ export class FunnelChartWidgetComponent implements OnInit {
}
this.legendSettings = { visible: true };
}
ngOnChanges(changes: SimpleChanges): void {
if (changes['config'] && this.config && this.config.datasetId) {
this.loadData();
} else if (changes['config'] && (!this.config || !this.config.datasetId)) {
this.chartData = [
{ x: 'Website Visitors', y: 10000 },
{ x: 'Leads', y: 8000 },
{ x: 'Opportunities', y: 6000 },
{ x: 'Converted', y: 4000 },
];
}
}
loadData(): void {
if (this.config.datasetId) {
this.datasetService.getDatasetById(this.config.datasetId).subscribe((dataset: DatasetModel | undefined) => {
if (dataset && dataset.url) {
this.http.get<any[]>(dataset.url).subscribe(data => {
this.chartData = data.map(item => ({ x: item[this.config.xField], y: item[this.config.yField] }));
if (this.config.title) {
this.title = this.config.title;
}
});
}
});
}
}
}
import { Component, Input, OnInit } from '@angular/core';
import { Component, Input, OnInit, SimpleChanges } from '@angular/core';
import { CommonModule } from '@angular/common';
import { CircularGaugeModule, GaugeTooltipService, AnnotationsService } from '@syncfusion/ej2-angular-circulargauge';
import { DatasetModel } from '../../models/widgets.model';
import { DatasetService } from '../../services/dataset.service';
import { HttpClient } from '@angular/common/http';
@Component({
selector: 'app-gauge-chart-widget',
......@@ -10,11 +13,14 @@ import { CircularGaugeModule, GaugeTooltipService, AnnotationsService } from '@s
templateUrl: './gauge-chart-widget.component.html',
})
export class GaugeChartWidgetComponent implements OnInit {
@Input() config: any;
@Input() value: number = 70;
@Input() title: string = 'Gauge Chart';
public axes: Object[];
constructor(private datasetService: DatasetService, private http: HttpClient) { }
ngOnInit(): void {
this.axes = [{
line: { width: 0 },
......@@ -34,5 +40,51 @@ export class GaugeChartWidgetComponent implements OnInit {
{ start: 75, end: 100, color: '#B9EAB9' }
]
}];
if (!this.config || !this.config.datasetId) {
this.value = 70;
}
}
ngOnChanges(changes: SimpleChanges): void {
if (changes['config'] && this.config && this.config.datasetId) {
this.loadData();
} else if (changes['config'] && (!this.config || !this.config.datasetId)) {
this.value = 70;
}
}
loadData(): void {
if (this.config.datasetId) {
this.datasetService.getDatasetById(this.config.datasetId).subscribe((dataset: DatasetModel | undefined) => {
if (dataset && dataset.url) {
this.http.get<any[]>(dataset.url).subscribe(data => {
if (this.config.valueField && data.length > 0) {
this.value = data[0][this.config.valueField]; // Assuming single value for gauge
}
if (this.config.title) {
this.title = this.config.title;
}
this.axes = [{
line: { width: 0 },
labelStyle: { font: { size: '0px' } },
majorTicks: { height: 0 },
minorTicks: { height: 0 },
pointers: [{
value: this.value,
radius: '80%',
pointerWidth: 8,
cap: { radius: 7 },
needleTail: { length: '18%' }
}],
ranges: [
{ start: 0, end: 50, color: '#E0B9B9' },
{ start: 50, end: 75, color: '#B9D7EA' },
{ start: 75, end: 100, color: '#B9EAB9' }
]
}];
});
}
});
}
}
}
<div class="bg-white p-6 rounded-lg shadow-md flex flex-col justify-between h-full">
<div>
<h3 class="text-lg font-semibold text-gray-500">{{ kpiName }}</h3>
<p class="text-4xl font-bold text-gray-800 mt-2">{{ kpiData.value }}</p>
<div class="p-4 bg-white rounded-lg shadow-md h-full flex flex-col justify-between">
<div>
<h5 class="text-lg font-semibold text-gray-600 mb-2">{{ kpiName }}</h5>
<div class="text-4xl font-bold text-gray-800">
{{ kpiData.value }}<span *ngIf="kpiData.unit" class="text-2xl ml-1">{{ kpiData.unit }}</span>
</div>
<div *ngIf="kpiData.trendValue" class="flex items-center text-sm">
<span *ngIf="kpiData.trend === 'up'" class="text-green-500 flex items-center">
<svg class="w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 15l7-7 7 7"></path></svg>
{{ kpiData.trendValue }}
</span>
<span *ngIf="kpiData.trend === 'down'" class="text-red-500 flex items-center">
<svg class="w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path></svg>
{{ kpiData.trendValue }}
</span>
<span *ngIf="kpiData.trend === 'neutral' && kpiData.trendValue" class="text-gray-500">
{{ kpiData.trendValue }}
</span>
</div>
</div>
</div>
<div class="flex items-center mt-4 text-sm" [ngClass]="{'text-emerald-500': kpiData.trend === 'up', 'text-rose-500': kpiData.trend === 'down'}">
<svg *ngIf="kpiData.trend === 'up'" xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-1" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-8.707a1 1 0 00-1.414-1.414L11 9.586V6a1 1 0 10-2 0v3.586l-1.293-1.293a1 1 0 00-1.414 1.414l3 3a1 1 0 001.414 0l3-3z" clip-rule="evenodd" />
</svg>
<svg *ngIf="kpiData.trend === 'down'" xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-1" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm-3.707-7.293a1 1 0 011.414 0L9 11.414V14a1 1 0 112 0v-2.586l1.293-1.293a1 1 0 011.414 1.414l-3 3a1 1 0 01-1.414 0l-3-3a1 1 0 010-1.414z" clip-rule="evenodd" />
</svg>
<span>{{ kpiData.percentage }}%</span>
<span class="ml-1">vs last month</span>
</div>
</div>
import { Component, Input, OnInit } from '@angular/core';
import { Component, Input, OnInit, OnChanges, SimpleChanges } from '@angular/core';
import { CommonModule } from '@angular/common';
import { HttpClient, HttpClientModule } from '@angular/common/http';
import { DatasetService } from '../../services/dataset.service';
import { DatasetModel } from '../../models/widgets.model';
import { MockDataService } from '../../common/mock-data.service';
@Component({
selector: 'app-kpi-widget',
standalone: true,
imports: [CommonModule],
imports: [CommonModule, HttpClientModule],
providers: [DatasetService, HttpClient, MockDataService],
templateUrl: './kpi-widget.component.html',
})
export class KpiWidgetComponent implements OnInit {
export class KpiWidgetComponent implements OnInit, OnChanges {
@Input() kpiName: string = 'New Hires'; // Default KPI
@Input() config: any;
kpiData!: { value: number, trend: 'up' | 'down' | 'flat', percentage: number };
// kpiData!: { value: number, trend: 'up' | 'down' | 'flat', percentage: number, unit: string, trendValue: string };
kpiData: any
constructor(private mockDataService: MockDataService) { }
ngOnInit(): void {
this.kpiData = this.mockDataService.getKpiData(this.kpiName);
}
ngOnChanges(changes: SimpleChanges): void {
if (changes['kpiName']) {
this.kpiData = this.mockDataService.getKpiData(this.kpiName);
}
}
}
import { Component, Input, OnInit } from '@angular/core';
import { Component, Input, OnInit, OnChanges, SimpleChanges } from '@angular/core';
import { CommonModule } from '@angular/common';
import { DatasetService } from '../../services/dataset.service';
import { HttpClient, HttpClientModule } from '@angular/common/http';
import { DatasetModel } from '../../models/widgets.model';
@Component({
selector: 'app-matrix-widget',
standalone: true,
imports: [CommonModule],
imports: [CommonModule, HttpClientModule],
providers: [DatasetService, HttpClient],
templateUrl: './matrix-widget.component.html',
styleUrls: ['./matrix-widget.component.scss']
})
export class MatrixWidgetComponent implements OnInit {
export class MatrixWidgetComponent implements OnInit, OnChanges {
@Input() title: string = 'Matrix';
@Input() headers: string[] = [];
@Input() data: any[][] = [];
@Input() config: any;
constructor(private datasetService: DatasetService, private http: HttpClient) { }
ngOnInit(): void {
if (this.headers.length === 0) {
if (!this.config || !this.config.datasetId) {
this.headers = ['Category', 'Q1', 'Q2', 'Q3', 'Q4'];
this.data = [
['Product A', 100, 120, 150, 130],
['Product B', 80, 90, 110, 100],
['Product C', 150, 130, 160, 140],
];
}
if (this.data.length === 0) {
}
ngOnChanges(changes: SimpleChanges): void {
if (changes['config'] && this.config && this.config.datasetId) {
this.loadData();
} else if (changes['config'] && (!this.config || !this.config.datasetId)) {
this.headers = ['Category', 'Q1', 'Q2', 'Q3', 'Q4'];
this.data = [
['Product A', 100, 120, 150, 130],
['Product B', 80, 90, 110, 100],
......@@ -25,4 +43,22 @@ export class MatrixWidgetComponent implements OnInit {
];
}
}
loadData(): void {
if (this.config.datasetId) {
this.datasetService.getDatasetById(this.config.datasetId).subscribe((dataset: DatasetModel | undefined) => {
if (dataset && dataset.url) {
this.http.get<any[]>(dataset.url).subscribe(data => {
if (this.config.columns && data.length > 0) {
this.headers = this.config.columns.map((col: any) => col.headerText);
this.data = data.map(row => this.config.columns.map((col: any) => row[col.field]));
}
if (this.config.title) {
this.title = this.config.title;
}
});
}
});
}
}
}
import { Component, Input, OnInit } from '@angular/core';
import { Component, Input, OnInit, SimpleChanges } from '@angular/core';
import { CommonModule } from '@angular/common';
import { DatasetModel } from '../../models/widgets.model';
import { DatasetService } from '../../services/dataset.service';
import { HttpClient } from '@angular/common/http';
@Component({
selector: 'app-multi-row-card-widget',
......@@ -9,11 +12,24 @@ import { CommonModule } from '@angular/common';
styleUrls: ['./multi-row-card-widget.component.scss']
})
export class MultiRowCardWidgetComponent implements OnInit {
@Input() config: any;
@Input() cardData: any[];
@Input() title: string = 'Multi-Row Card';
constructor(private datasetService: DatasetService, private http: HttpClient) { }
ngOnInit(): void {
if (!this.cardData) {
if (!this.config || !this.config.datasetId) {
this.cardData = [
{ label: 'Total Sales', value: '1,234,567', unit: 'USD' },
{ label: 'New Customers', value: '5,432', unit: '' },
{ label: 'Conversion Rate', value: '12.34', unit: '%' },
];
}
}
ngOnChanges(changes: SimpleChanges): void {
if (changes['config'] && this.config && this.config.datasetId) {
this.loadData();
} else if (changes['config'] && (!this.config || !this.config.datasetId)) {
this.cardData = [
{ label: 'Total Sales', value: '1,234,567', unit: 'USD' },
{ label: 'New Customers', value: '5,432', unit: '' },
......@@ -21,4 +37,23 @@ export class MultiRowCardWidgetComponent implements OnInit {
];
}
}
loadData(): void {
if (this.config.datasetId) {
this.datasetService.getDatasetById(this.config.datasetId).subscribe((dataset: DatasetModel | undefined) => {
if (dataset && dataset.url) {
this.http.get<any[]>(dataset.url).subscribe(data => {
this.cardData = data.map(item => ({
label: item[this.config.labelField],
value: item[this.config.valueField],
unit: item[this.config.unitField] || ''
}));
if (this.config.title) {
this.title = this.config.title;
}
});
}
});
}
}
}
import { Component, Input, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-payroll-widget',
standalone: true,
imports: [CommonModule],
templateUrl: './payroll-widget.component.html',
styleUrls: ['./payroll-widget.component.scss']
})
......
<ejs-accumulationchart [title]="title" [legendSettings]="legendSettings" [enableSmartLabels]="true">
<e-accumulation-series-collection>
<e-accumulation-series [dataSource]="chartData" xName="browser" yName="users" [dataLabel]="{ visible: true, name: 'text', position: 'Inside' }"></e-accumulation-series>
<e-accumulation-series [dataSource]="chartData" type="Pie" xName="x" yName="y" [dataLabel]="{ visible: true, name: 'text', position: 'Inside' }"></e-accumulation-series>
</e-accumulation-series-collection>
</ejs-accumulationchart>
import { Component, Input, OnInit } from '@angular/core';
import { Component, Input, OnInit, OnChanges, SimpleChanges } from '@angular/core';
import { CommonModule } from '@angular/common';
import { AccumulationChartModule, PieSeriesService, AccumulationDataLabelService, AccumulationLegendService, AccumulationTooltipService } from '@syncfusion/ej2-angular-charts';
import { DatasetService } from '../../services/dataset.service';
import { HttpClient, HttpClientModule } from '@angular/common/http';
import { DatasetModel } from '../../models/widgets.model';
@Component({
selector: 'app-pie-chart-widget',
standalone: true,
imports: [CommonModule, AccumulationChartModule],
providers: [PieSeriesService, AccumulationDataLabelService, AccumulationLegendService, AccumulationTooltipService],
imports: [CommonModule, AccumulationChartModule, HttpClientModule],
providers: [PieSeriesService, AccumulationDataLabelService, AccumulationLegendService, AccumulationTooltipService, DatasetService, HttpClient],
templateUrl: './pie-chart-widget.component.html',
})
export class PieChartWidgetComponent implements OnInit {
export class PieChartWidgetComponent implements OnInit, OnChanges {
@Input() chartData: Object[];
@Input() title: string = 'Pie Chart';
@Input() legendSettings: Object;
@Input() config: any;
constructor(private datasetService: DatasetService, private http: HttpClient) { }
ngOnInit(): void {
if (!this.chartData) {
if (!this.config || !this.config.datasetId) {
this.chartData = [
{ browser: 'Chrome', users: 37 },
{ browser: 'Firefox', users: 17 },
......@@ -27,4 +33,47 @@ export class PieChartWidgetComponent implements OnInit {
}
this.legendSettings = { visible: true };
}
ngOnChanges(changes: SimpleChanges): void {
if (changes['config'] && this.config && this.config.datasetId) {
this.loadData();
} else if (changes['config'] && (!this.config || !this.config.datasetId)) {
this.chartData = [
{ browser: 'Chrome', users: 37 },
{ browser: 'Firefox', users: 17 },
{ browser: 'Internet Explorer', users: 19 },
{ browser: 'Edge', users: 4 },
{ browser: 'Safari', users: 11 },
{ browser: 'Other', users: 12 },
];
}
}
loadData(): void {
if (this.config.datasetId) {
this.datasetService.getDatasetById(this.config.datasetId).subscribe((dataset: DatasetModel | undefined) => {
if (dataset && dataset.url) {
this.http.get<any[]>(dataset.url).subscribe(data => {
let transformedData = data;
if (this.config.xField && this.config.yField) {
if (this.config.aggregation === 'count') {
const counts = transformedData.reduce((acc, item) => {
const key = item[this.config.xField];
acc[key] = (acc[key] || 0) + 1;
return acc;
}, {});
transformedData = Object.keys(counts).map(key => ({ x: key, y: counts[key] }));
} else {
transformedData = transformedData.map(item => ({ x: item[this.config.xField], y: item[this.config.yField] }));
}
}
this.chartData = transformedData;
if (this.config.title) {
this.title = this.config.title;
}
});
}
});
}
}
}
<div class="bg-white p-6 rounded-lg shadow-md h-full flex flex-col">
<h3 class="text-lg font-semibold text-gray-500 mb-4">Quick Links</h3>
<ul class="space-y-2">
<li *ngFor="let link of quickLinks">
<a [href]="link.url" class="text-indigo-600 hover:text-indigo-800 hover:underline text-base font-medium block p-2 rounded-md transition-colors duration-200 hover:bg-indigo-50">
{{ link.name }}
</a>
</li>
</ul>
<div class="card h-100">
<div class="card-header">
<h5 class="card-title">Quick Links</h5>
</div>
<div class="card-body">
<ul>
<li *ngFor="let link of quickLinks">
<a [href]="link.url" target="_blank" class="text-blue-500 hover:underline">{{ link.name }}</a>
</li>
</ul>
</div>
</div>
import { Component, Input, OnInit } from '@angular/core';
import { Component, Input, OnInit, OnChanges, SimpleChanges } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MockDataService } from '../../common/mock-data.service';
import { DatasetService } from '../../services/dataset.service';
import { HttpClient, HttpClientModule } from '@angular/common/http';
import { DatasetModel } from '../../models/widgets.model';
@Component({
selector: 'app-quick-links-widget',
standalone: true,
imports: [CommonModule],
imports: [CommonModule, HttpClientModule],
providers: [DatasetService, HttpClient],
templateUrl: './quick-links-widget.component.html',
})
export class QuickLinksWidgetComponent implements OnInit {
export class QuickLinksWidgetComponent implements OnInit, OnChanges {
@Input() links: { name: string, url: string }[] | undefined; // New input for links
@Input() config: any;
quickLinks: { name: string, url: string }[] = [];
constructor(private mockDataService: MockDataService) { }
constructor(private datasetService: DatasetService, private http: HttpClient) { }
ngOnInit(): void {
this.quickLinks = this.links || this.mockDataService.getQuickLinks();
if (!this.config || !this.config.datasetId) {
this.quickLinks = [
{ name: 'Google', url: 'https://www.google.com' },
{ name: 'Angular', url: 'https://angular.io' },
];
}
}
ngOnChanges(changes: SimpleChanges): void {
if (changes['config'] && this.config && this.config.datasetId) {
this.loadData();
} else if (changes['config'] && (!this.config || !this.config.datasetId)) {
this.quickLinks = [
{ name: 'Google', url: 'https://www.google.com' },
{ name: 'Angular', url: 'https://angular.io' },
];
}
}
loadData(): void {
if (this.config.datasetId) {
this.datasetService.getDatasetById(this.config.datasetId).subscribe((dataset: DatasetModel | undefined) => {
if (dataset && dataset.url) {
this.http.get<any[]>(dataset.url).subscribe(data => {
if (this.config.nameField && this.config.urlField) {
this.quickLinks = data.map(item => ({ name: item[this.config.nameField], url: item[this.config.urlField] }));
}
});
}
});
}
}
}
<ejs-chart [title]="title" [primaryXAxis]="primaryXAxis" [primaryYAxis]="primaryYAxis">
<e-series-collection>
<e-series [dataSource]="chartData" [type]="type" xName="x" yName="y" size="size" name="Data"></e-series>
<e-series [dataSource]="chartData" [type]="type" xName="x" yName="y" [size]="config?.sizeField" name="Data"></e-series>
</e-series-collection>
</ejs-chart>
import { Component, Input, OnInit } from '@angular/core';
import { Component, Input, OnInit, OnChanges, SimpleChanges } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ChartModule, ScatterSeriesService, BubbleSeriesService, CategoryService, LegendService, TooltipService, DataLabelService } from '@syncfusion/ej2-angular-charts';
import { DatasetService } from '../../services/dataset.service';
import { HttpClient, HttpClientModule } from '@angular/common/http';
import { DatasetModel } from '../../models/widgets.model';
@Component({
selector: 'app-scatter-bubble-chart-widget',
standalone: true,
imports: [CommonModule, ChartModule],
providers: [ScatterSeriesService, BubbleSeriesService, CategoryService, LegendService, TooltipService, DataLabelService],
imports: [CommonModule, ChartModule, HttpClientModule],
providers: [ScatterSeriesService, BubbleSeriesService, CategoryService, LegendService, TooltipService, DataLabelService, DatasetService, HttpClient],
templateUrl: './scatter-bubble-chart-widget.component.html',
})
export class ScatterBubbleChartWidgetComponent implements OnInit {
export class ScatterBubbleChartWidgetComponent implements OnInit, OnChanges {
@Input() chartData: Object[];
@Input() title: string = 'Scatter & Bubble Chart';
@Input() type: 'Scatter' | 'Bubble' = 'Scatter';
@Input() config: any;
public primaryXAxis: Object;
public primaryYAxis: Object;
constructor(private datasetService: DatasetService, private http: HttpClient) { }
ngOnInit(): void {
this.primaryXAxis = { title: 'X-Value' };
this.primaryYAxis = { title: 'Y-Value' };
if (!this.chartData) {
if (!this.config || !this.config.datasetId) {
if (this.type === 'Scatter') {
this.chartData = [
{ x: 10, y: 35 }, { x: 15, y: 28 },
{ x: 20, y: 34 }, { x: 25, y: 32 },
{ x: 30, y: 40 }, { x: 35, y: 30 },
];
} else { // Bubble
this.chartData = [
{ x: 10, y: 35, size: 5 }, { x: 15, y: 28, size: 8 },
{ x: 20, y: 34, size: 6 }, { x: 25, y: 32, size: 10 },
{ x: 30, y: 40, size: 7 }, { x: 35, y: 30, size: 9 },
];
}
}
}
ngOnChanges(changes: SimpleChanges): void {
if (changes['config'] && this.config && this.config.datasetId) {
this.loadData();
} else if (changes['config'] && (!this.config || !this.config.datasetId)) {
if (this.type === 'Scatter') {
this.chartData = [
{ x: 10, y: 35 }, { x: 15, y: 28 },
......@@ -36,4 +62,32 @@ export class ScatterBubbleChartWidgetComponent implements OnInit {
}
}
}
loadData(): void {
if (this.config.datasetId) {
this.datasetService.getDatasetById(this.config.datasetId).subscribe((dataset: DatasetModel | undefined) => {
if (dataset && dataset.url) {
this.http.get<any[]>(dataset.url).subscribe(data => {
if (this.config.type === 'Bubble') {
this.chartData = data.map(item => ({ x: item[this.config.xField], y: item[this.config.yField], size: item[this.config.sizeField] }));
} else {
this.chartData = data.map(item => ({ x: item[this.config.xField], y: item[this.config.yField] }));
}
if (this.config.title) {
this.title = this.config.title;
}
if (this.config.xAxisTitle) {
this.primaryXAxis = { ...this.primaryXAxis, title: this.config.xAxisTitle };
}
if (this.config.yAxisTitle) {
this.primaryYAxis = { ...this.primaryYAxis, title: this.config.yAxisTitle };
}
if (this.config.type) {
this.type = this.config.type;
}
});
}
});
}
}
}
import { Component, Input, OnInit } from '@angular/core';
import { Component, Input, OnInit, OnChanges, SimpleChanges } from '@angular/core';
import { CommonModule } from '@angular/common';
import { DatasetService } from '../../services/dataset.service';
import { HttpClient, HttpClientModule } from '@angular/common/http';
import { DatasetModel } from '../../models/widgets.model';
@Component({
selector: 'app-simple-kpi-widget',
standalone: true,
imports: [CommonModule],
imports: [CommonModule, HttpClientModule],
providers: [DatasetService, HttpClient],
templateUrl: './simple-kpi-widget.component.html',
styleUrls: ['./simple-kpi-widget.component.scss']
})
export class SimpleKpiWidgetComponent implements OnInit {
export class SimpleKpiWidgetComponent implements OnInit, OnChanges {
@Input() title: string = 'Key Performance Indicator';
@Input() value: string = '123,456';
@Input() unit: string = '';
@Input() trend: 'up' | 'down' | 'neutral' = 'neutral';
@Input() trendValue: string = '';
@Input() config: any;
constructor(private datasetService: DatasetService, private http: HttpClient) { }
ngOnInit(): void {
if (!this.config || !this.config.datasetId) {
this.value = '123,456';
this.unit = '';
this.trend = 'neutral';
this.trendValue = '';
}
}
ngOnChanges(changes: SimpleChanges): void {
if (changes['config'] && this.config && this.config.datasetId) {
this.loadData();
} else if (changes['config'] && (!this.config || !this.config.datasetId)) {
this.value = '123,456';
this.unit = '';
this.trend = 'neutral';
this.trendValue = '';
}
}
loadData(): void {
if (this.config.datasetId) {
this.datasetService.getDatasetById(this.config.datasetId).subscribe((dataset: DatasetModel | undefined) => {
if (dataset && dataset.url) {
this.http.get<any[]>(dataset.url).subscribe(data => {
if (data.length > 0) {
let kpiValue = data[0][this.config.valueField];
if (this.config.aggregation === 'count') {
kpiValue = data.length;
} else if (this.config.aggregation === 'sum') {
kpiValue = data.reduce((sum, item) => sum + (item[this.config.valueField] || 0), 0);
}
this.value = kpiValue.toLocaleString();
this.unit = this.config.unit || '';
this.trend = this.config.trend || 'neutral';
this.trendValue = this.config.trendValue || '';
}
if (this.config.title) {
this.title = this.config.title;
}
});
}
});
}
}
}
import { Component, Input, OnInit } from '@angular/core';
import { Component, Input, OnInit, OnChanges, SimpleChanges } from '@angular/core';
import { CommonModule } from '@angular/common';
import { DatasetModel } from '../../models/widgets.model';
import { DatasetService } from '../../services/dataset.service';
import { HttpClient, HttpClientModule } from '@angular/common/http';
@Component({
selector: 'app-simple-table-widget',
standalone: true,
imports: [CommonModule],
imports: [CommonModule, HttpClientModule],
providers: [DatasetService, HttpClient],
templateUrl: './simple-table-widget.component.html',
styleUrls: ['./simple-table-widget.component.scss']
})
export class SimpleTableWidgetComponent implements OnInit {
export class SimpleTableWidgetComponent implements OnInit, OnChanges {
@Input() config: any;
@Input() title: string = 'Table';
@Input() headers: string[] = [];
@Input() data: any[][] = [];
constructor(private datasetService: DatasetService, private http: HttpClient) { }
ngOnInit(): void {
if (this.headers.length === 0) {
if (!this.config || !this.config.datasetId) {
this.headers = ['ID', 'Name', 'Status'];
this.data = [
[1, 'Item A', 'Active'],
[2, 'Item B', 'Inactive'],
[3, 'Item C', 'Active'],
];
}
if (this.data.length === 0) {
}
ngOnChanges(changes: SimpleChanges): void {
if (changes['config'] && this.config && this.config.datasetId) {
this.loadData();
} else if (changes['config'] && (!this.config || !this.config.datasetId)) {
this.headers = ['ID', 'Name', 'Status'];
this.data = [
[1, 'Item A', 'Active'],
[2, 'Item B', 'Inactive'],
......@@ -25,4 +43,22 @@ export class SimpleTableWidgetComponent implements OnInit {
];
}
}
loadData(): void {
if (this.config.datasetId) {
this.datasetService.getDatasetById(this.config.datasetId).subscribe((dataset: DatasetModel | undefined) => {
if (dataset && dataset.url) {
this.http.get<any[]>(dataset.url).subscribe(data => {
if (this.config.columns && data.length > 0) {
this.headers = this.config.columns.map((col: any) => col.headerText);
this.data = data.map(row => this.config.columns.map((col: any) => row[col.field]));
}
if (this.config.title) {
this.title = this.config.title;
}
});
}
});
}
}
}
import { Component, Input, OnInit, Output, EventEmitter } from '@angular/core';
import { Component, Input, OnInit, Output, EventEmitter, SimpleChanges, OnChanges } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { DatasetModel } from '../../models/widgets.model';
import { DatasetService } from '../../services/dataset.service';
import { HttpClient } from '@angular/common/http';
@Component({
selector: 'app-slicer-widget',
standalone: true,
......@@ -9,19 +11,51 @@ import { FormsModule } from '@angular/forms';
templateUrl: './slicer-widget.component.html',
styleUrls: ['./slicer-widget.component.scss']
})
export class SlicerWidgetComponent implements OnInit {
@Input() title: string = 'Slicer';
@Input() options: string[] = [];
@Input() selectedValue: string = '';
export class SlicerWidgetComponent implements OnInit, OnChanges {
@Input() config: any;
public title: string = 'Slicer';
public options: string[] = [];
public selectedValue: string = '';
@Output() selectionChange = new EventEmitter<string>();
constructor(private datasetService: DatasetService, private http: HttpClient) { }
ngOnInit(): void {
if (this.options.length === 0) {
if (!this.config || !this.config.datasetId) {
this.options = ['All', 'Option 1', 'Option 2', 'Option 3'];
this.selectedValue = this.options[0];
}
}
ngOnChanges(changes: SimpleChanges): void {
if (changes['config'] && this.config && this.config.datasetId) {
this.loadData();
} else if (changes['config'] && (!this.config || !this.config.datasetId)) {
this.options = ['All', 'Option 1', 'Option 2', 'Option 3'];
this.selectedValue = this.options[0];
}
}
loadData(): void {
if (this.config.datasetId) {
this.datasetService.getDatasetById(this.config.datasetId).subscribe((dataset: DatasetModel | undefined) => {
if (dataset && dataset.url) {
this.http.get<any[]>(dataset.url).subscribe((data: any[]) => {
if (this.config.optionsField) {
const uniqueOptions = [...new Set(data.map((item: any) => item[this.config.optionsField]))];
this.options = ['All', ...uniqueOptions.map(String)]; // Ensure options are strings
this.selectedValue = this.options[0];
}
if (this.config.title) {
this.title = this.config.title;
}
});
}
});
}
}
onSelectionChange(): void {
this.selectionChange.emit(this.selectedValue);
}
......
<div class="bg-white p-4 rounded-lg shadow-md h-full flex flex-col">
<h3 class="text-lg font-semibold text-gray-500 mb-4">{{ title }}</h3>
<ejs-chart id='chart-container' [primaryXAxis]='primaryXAxis' [title]='title' class="flex-grow">
<ejs-chart [title]="title" [primaryXAxis]="primaryXAxis" [primaryYAxis]="primaryYAxis">
<e-series-collection>
<e-series type='Column' [dataSource]='chartData' xName='month' yName='sales' name='Sales'></e-series>
<e-series [dataSource]="chartData" type="Column" xName="x" yName="y" name="Data"></e-series>
</e-series-collection>
</ejs-chart>
</ejs-chart>
</div>
import { Component, Input, OnInit } from '@angular/core';
import { Component, Input, OnInit, OnChanges, SimpleChanges } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ChartModule, ColumnSeriesService, CategoryService, LegendService, TooltipService, DataLabelService } from '@syncfusion/ej2-angular-charts';
import { DatasetService } from '../../services/dataset.service';
import { HttpClient, HttpClientModule } from '@angular/common/http';
import { DatasetModel } from '../../models/widgets.model';
@Component({
selector: 'app-syncfusion-chart-widget',
standalone: true,
imports: [CommonModule, ChartModule],
providers: [ColumnSeriesService, CategoryService, LegendService, TooltipService, DataLabelService],
imports: [CommonModule, ChartModule, HttpClientModule],
providers: [ColumnSeriesService, CategoryService, LegendService, TooltipService, DataLabelService, DatasetService, HttpClient],
templateUrl: './syncfusion-chart-widget.component.html',
})
export class SyncfusionChartWidgetComponent implements OnInit {
export class SyncfusionChartWidgetComponent implements OnInit, OnChanges {
@Input() title: string = 'Monthly Sales Analysis'; // New input for title
@Input() chartData: Object[] | undefined; // New input for chart data
@Input() config: any;
public primaryXAxis: Object;
public primaryYAxis: Object;
public localChartData: Object[]; // Renamed to avoid conflict with input
constructor() {
constructor(private datasetService: DatasetService, private http: HttpClient) {
this.localChartData = this.chartData || [
{ month: 'Jan', sales: 35 }, { month: 'Feb', sales: 28 },
{ month: 'Mar', sales: 34 }, { month: 'Apr', sales: 32 },
......@@ -30,8 +35,52 @@ export class SyncfusionChartWidgetComponent implements OnInit {
ngOnInit(): void {
// If chartData is provided as an input, update localChartData
if (this.chartData) {
this.localChartData = this.chartData;
if (!this.config || !this.config.datasetId) {
this.chartData = [
{ month: 'Jan', sales: 35 }, { month: 'Feb', sales: 28 },
{ month: 'Mar', sales: 34 }, { month: 'Apr', sales: 32 },
{ month: 'May', sales: 40 }, { month: 'Jun', sales: 30 },
{ month: 'Jul', sales: 35 }, { month: 'Aug', sales: 37 },
{ month: 'Sep', sales: 39 }, { month: 'Oct', sales: 30 },
{ month: 'Nov', sales: 35 }, { month: 'Dec', sales: 41 }
];
}
this.primaryXAxis = { valueType: 'Category' };
}
ngOnChanges(changes: SimpleChanges): void {
if (changes['config'] && this.config && this.config.datasetId) {
this.loadData();
} else if (changes['config'] && (!this.config || !this.config.datasetId)) {
this.chartData = [
{ month: 'Jan', sales: 35 }, { month: 'Feb', sales: 28 },
{ month: 'Mar', sales: 34 }, { month: 'Apr', sales: 32 },
{ month: 'May', sales: 40 }, { month: 'Jun', sales: 30 },
{ month: 'Jul', sales: 35 }, { month: 'Aug', sales: 37 },
{ month: 'Sep', sales: 39 }, { month: 'Oct', sales: 30 },
{ month: 'Nov', sales: 35 }, { month: 'Dec', sales: 41 }
];
}
}
loadData(): void {
if (this.config.datasetId) {
this.datasetService.getDatasetById(this.config.datasetId).subscribe((dataset: DatasetModel | undefined) => {
if (dataset && dataset.url) {
this.http.get<any[]>(dataset.url).subscribe(data => {
this.chartData = data.map(item => ({ x: item[this.config.xField], y: item[this.config.yField] }));
if (this.config.title) {
this.title = this.config.title;
}
if (this.config.xAxisTitle) {
this.primaryXAxis = { ...this.primaryXAxis, title: this.config.xAxisTitle };
}
if (this.config.yAxisTitle) {
this.primaryYAxis = { ...this.primaryYAxis, title: this.config.yAxisTitle };
}
});
}
});
}
}
}
<div class="bg-white p-4 rounded-lg shadow-md h-full flex flex-col">
<h3 class="text-lg font-semibold text-gray-500 mb-4">Order Data Grid</h3>
<ejs-grid [dataSource]='data' [allowPaging]='true' [pageSettings]='pageSettings' [allowSorting]='true' [allowFiltering]='true' [allowGrouping]='true' class="flex-grow">
<e-columns>
<e-column field='OrderID' headerText='Order ID' textAlign='Right' width='120'></e-column>
<e-column field='CustomerID' headerText='Customer Name' width='150'></e-column>
<e-column field='EmployeeID' headerText='Employee ID' textAlign='Right' width='120'></e-column>
<e-column field='ShipCity' headerText='Ship City' width='150'></e-column>
</e-columns>
</ejs-grid>
</div>
<div class="h-full">
<h5 class="text-lg font-semibold text-gray-600 mb-2">{{ title }}</h5>
<ejs-grid [dataSource]="data" [allowPaging]="true" [pageSettings]="pageSettings" [allowSorting]="true" [allowFiltering]="true" [allowGrouping]="true">
<e-columns>
<e-column *ngFor="let col of columns" [field]="col.field" [headerText]="col.headerText" [width]="col.width"></e-column>
</e-columns>
</ejs-grid>
</div>
......@@ -14,36 +14,54 @@ import { DatasetModel } from '../../models/widgets.model';
templateUrl: './syncfusion-datagrid-widget.component.html',
})
export class SyncfusionDatagridWidgetComponent implements OnInit, OnChanges {
@Input() title: string = 'Data Grid';
@Input() datasetId: string;
@Input() config: any;
public data: object[] = [];
public columns: any[] = [];
public title: string = 'Data Grid';
public pageSettings: Object = { pageSize: 6 };
constructor(private datasetService: DatasetService, private http: HttpClient, private cdr: ChangeDetectorRef) {}
ngOnInit(): void {
if (!this.config || !this.config.datasetId) {
this.data = [];
this.columns = [];
}
this.loadData();
}
ngOnChanges(changes: SimpleChanges): void {
if (changes['datasetId']) {
if (changes['config'] && this.config && this.config.datasetId) {
this.loadData();
} else if (changes['config'] && (!this.config || !this.config.datasetId)) {
this.data = [];
this.columns = [];
}
}
loadData(): void {
if (this.datasetId) {
this.datasetService.getDatasetById(this.datasetId).subscribe((dataset: DatasetModel | undefined) => {
if (this.config.datasetId) {
this.datasetService.getDatasetById(this.config.datasetId).subscribe((dataset: DatasetModel | undefined) => {
if (dataset && dataset.url) {
this.http.get<object[]>(dataset.url).subscribe(data => {
this.data = data;
if (this.config.columns) {
this.columns = this.config.columns;
} else if (this.data.length > 0) {
// Auto-generate columns if not provided in config
this.columns = Object.keys(this.data[0]).map(key => ({ field: key, headerText: key }));
}
if (this.config.title) {
this.title = this.config.title;
}
this.cdr.markForCheck();
});
}
});
} else {
this.data = [];
this.columns = [];
}
}
}
<div class="bg-white p-4 rounded-lg shadow-md h-full flex flex-col">
<h3 class="text-lg font-semibold text-gray-500 mb-4">Sales Pivot Analysis</h3>
<ejs-pivotview #pivotview id='PivotView' [dataSourceSettings]='dataSourceSettings' [height]='"100%"' [width]='"100%"' [showFieldList]='true' [showToolbar]='true' [allowCalculatedField]='true' [allowConditionalFormatting]='true' [allowGrouping='true'] class="flex-grow">
</ejs-pivotview>
</div>
<ejs-pivotview [dataSourceSettings]="dataSourceSettings" [allowCalculatedField]="true" [showFieldList]="true" [showToolbar]="true">
</ejs-pivotview>
import { Component, Input, OnInit } from '@angular/core';
import { Component, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core';
import { CommonModule } from '@angular/common';
import { PivotViewModule, IDataSet, FieldListService, CalculatedFieldService, ToolbarService, GroupingBarService, ConditionalFormattingService, LoadEventArgs } from '@syncfusion/ej2-angular-pivotview';
import { DatasetModel } from '../../models/widgets.model';
import { DatasetService } from '../../services/dataset.service';
import { HttpClient } from '@angular/common/http';
@Component({
selector: 'app-syncfusion-pivot-widget',
......@@ -9,52 +12,83 @@ import { PivotViewModule, IDataSet, FieldListService, CalculatedFieldService, To
providers: [FieldListService, CalculatedFieldService, ToolbarService, GroupingBarService, ConditionalFormattingService],
templateUrl: './syncfusion-pivot-widget.component.html',
})
export class SyncfusionPivotWidgetComponent implements OnInit {
@Input() title: string = 'Pivot Table'; // New input for title
@Input() pivotData: IDataSet[] | undefined; // New input for pivot data
export class SyncfusionPivotWidgetComponent implements OnInit, OnChanges {
@Input() config: any;
public dataSource: IDataSet[];
public dataSourceSettings: Object;
constructor() {
// Initialize with default data if no input is provided
this.dataSource = this.pivotData || [
{ 'Sold': 31, 'Amount': 52824, 'Country': 'France', 'Products': 'Mountain Bikes', 'Year': 'FY 2015' },
{ 'Sold': 51, 'Amount': 91915, 'Country': 'France', 'Products': 'Mountain Bikes', 'Year': 'FY 2016' },
{ 'Sold': 90, 'Amount': 173155, 'Country': 'France', 'Products': 'Mountain Bikes', 'Year': 'FY 2017' },
{ 'Sold': 25, 'Amount': 43750, 'Country': 'France', 'Products': 'Road Bikes', 'Year': 'FY 2015' },
{ 'Sold': 49, 'Amount': 76821, 'Country': 'France', 'Products': 'Road Bikes', 'Year': 'FY 2016' },
{ 'Sold': 60, 'Amount': 106000, 'Country': 'France', 'Products': 'Road Bikes', 'Year': 'FY 2017' },
{ 'Sold': 50, 'Amount': 85000, 'Country': 'Germany', 'Products': 'Mountain Bikes', 'Year': 'FY 2015' },
{ 'Sold': 63, 'Amount': 104060, 'Country': 'Germany', 'Products': 'Mountain Bikes', 'Year': 'FY 2016' },
{ 'Sold': 90, 'Amount': 173155, 'Country': 'Germany', 'Products': 'Mountain Bikes', 'Year': 'FY 2017' },
{ 'Sold': 29, 'Amount': 53000, 'Country': 'Germany', 'Products': 'Road Bikes', 'Year': 'FY 2015' },
{ 'Sold': 40, 'Amount': 68000, 'Country': 'Germany', 'Products': 'Road Bikes', 'Year': 'FY 2016' },
{ 'Sold': 55, 'Amount': 100000, 'Country': 'Germany', 'Products': 'Road Bikes', 'Year': 'FY 2017' },
{ 'Sold': 22, 'Amount': 40000, 'Country': 'United Kingdom', 'Products': 'Mountain Bikes', 'Year': 'FY 2015' },
{ 'Sold': 35, 'Amount': 60000, 'Country': 'United Kingdom', 'Products': 'Mountain Bikes', 'Year': 'FY 2016' },
{ 'Sold': 70, 'Amount': 140000, 'Country': 'United Kingdom', 'Products': 'Mountain Bikes', 'Year': 'FY 2017' },
{ 'Sold': 15, 'Amount': 30000, 'Country': 'United Kingdom', 'Products': 'Road Bikes', 'Year': 'FY 2015' },
{ 'Sold': 28, 'Amount': 50000, 'Country': 'United Kingdom', 'Products': 'Road Bikes', 'Year': 'FY 2016' },
{ 'Sold': 40, 'Amount': 70000, 'Country': 'United Kingdom', 'Products': 'Road Bikes', 'Year': 'FY 2017' }
];
constructor(private datasetService: DatasetService, private http: HttpClient) {
this.dataSource = [];
this.dataSourceSettings = {
dataSource: this.dataSource, // Use the data source that was set
dataSource: this.dataSource,
expandAll: false,
rows: [{ name: 'Country' }],
columns: [{ name: 'Year' }],
values: [{ name: 'Sold' }, { name: 'Amount' }],
rows: [],
columns: [],
values: [],
filters: [],
drilledMembers: [{ name: 'Country', items: ['France'] }]
};
}
ngOnInit(): void {
// If pivotData is provided as an input, update the dataSourceSettings
if (this.pivotData) {
this.dataSource = this.pivotData;
this.dataSourceSettings = { ...this.dataSourceSettings, dataSource: this.dataSource };
if (!this.config || !this.config.datasetId) {
this.dataSource = [
{ 'Sold': 31, 'Amount': 52824, 'Country': 'France', 'Products': 'Mountain Bikes', 'Year': 'FY 2015' },
{ 'Sold': 51, 'Amount': 91915, 'Country': 'France', 'Products': 'Mountain Bikes', 'Year': 'FY 2016' },
{ 'Sold': 90, 'Amount': 173155, 'Country': 'France', 'Products': 'Mountain Bikes', 'Year': 'FY 2017' },
];
this.dataSourceSettings = {
dataSource: this.dataSource,
expandAll: false,
rows: [{ name: 'Country' }],
columns: [{ name: 'Year' }],
values: [{ name: 'Sold' }, { name: 'Amount' }],
filters: [],
};
}
}
ngOnChanges(changes: SimpleChanges): void {
if (changes['config'] && this.config && this.config.datasetId) {
this.loadData();
} else if (changes['config'] && (!this.config || !this.config.datasetId)) {
this.dataSource = [
{ 'Sold': 31, 'Amount': 52824, 'Country': 'France', 'Products': 'Mountain Bikes', 'Year': 'FY 2015' },
{ 'Sold': 51, 'Amount': 91915, 'Country': 'France', 'Products': 'Mountain Bikes', 'Year': 'FY 2016' },
{ 'Sold': 90, 'Amount': 173155, 'Country': 'France', 'Products': 'Mountain Bikes', 'Year': 'FY 2017' },
];
this.dataSourceSettings = {
dataSource: this.dataSource,
expandAll: false,
rows: [{ name: 'Country' }],
columns: [{ name: 'Year' }],
values: [{ name: 'Sold' }, { name: 'Amount' }],
filters: [],
};
}
}
loadData(): void {
if (this.config.datasetId) {
this.datasetService.getDatasetById(this.config.datasetId).subscribe((dataset: DatasetModel | undefined) => {
if (dataset && dataset.url) {
this.http.get<any[]>(dataset.url).subscribe(data => {
this.dataSource = data;
this.dataSourceSettings = {
dataSource: this.dataSource,
expandAll: this.config.expandAll || false,
rows: this.config.rows || [],
columns: this.config.columns || [],
values: this.config.values || [],
filters: this.config.filters || [],
};
if (this.config.title) {
// Assuming there's a title property in the component for the pivot table
// this.title = this.config.title;
}
});
}
});
}
}
}
<div class="card h-100">
<div class="card-header">
<h5 class="card-title">Time Tracking</h5>
<h5 class="card-title">{{ title }}</h5>
</div>
<div class="card-body">
<p>This is a placeholder for time tracking information.</p>
<p *ngIf="data">Data received: {{ data | json }}</p>
<div class="card-body flex flex-col justify-center items-center">
<p class="text-xl font-semibold">Status: {{ status }}</p>
<p class="text-lg">Hours Today: {{ hours }}</p>
</div>
</div>
import { Component, Input, OnInit } from '@angular/core';
import { Component, Input, OnInit, SimpleChanges } from '@angular/core';
import { CommonModule } from '@angular/common';
import { DatasetService } from '../../services/dataset.service';
import { HttpClient } from '@angular/common/http';
import { DatasetModel } from '../../models/widgets.model';
@Component({
selector: 'app-time-tracking-widget',
standalone: true,
imports: [CommonModule],
templateUrl: './time-tracking-widget.component.html',
styleUrls: ['./time-tracking-widget.component.scss']
})
export class TimeTrackingWidgetComponent implements OnInit {
@Input() data: any;
@Input() config: any;
@Input() title: string = 'Time Tracking';
status: string = '';
hours: string = '';
constructor() { }
constructor(private datasetService: DatasetService, private http: HttpClient) { }
ngOnInit(): void {
if (!this.config || !this.config.datasetId) {
this.status = 'Clocked In';
this.hours = '8.0';
}
}
ngOnChanges(changes: SimpleChanges): void {
if (changes['config'] && this.config && this.config.datasetId) {
this.loadData();
} else if (changes['config'] && (!this.config || !this.config.datasetId)) {
this.status = 'Clocked In';
this.hours = '8.0';
}
}
loadData(): void {
if (this.config.datasetId) {
this.datasetService.getDatasetById(this.config.datasetId).subscribe((dataset: DatasetModel | undefined) => {
if (dataset && dataset.url) {
this.http.get<any[]>(dataset.url).subscribe(data => {
if (data.length > 0) {
this.status = this.config.statusField ? data[0][this.config.statusField] : 'N/A';
this.hours = this.config.hoursField ? data[0][this.config.hoursField] : 'N/A';
}
if (this.config.title) {
this.title = this.config.title;
}
});
}
});
}
}
}
import { Component, Input, OnInit } from '@angular/core';
import { Component, Input, OnInit, OnChanges, SimpleChanges } from '@angular/core';
import { CommonModule } from '@angular/common';
import { TreeMapModule, TreeMapTooltipService, TreeMapLegendService, TreeMapHighlightService, TreeMapSelectionService } from '@syncfusion/ej2-angular-treemap';
import { DatasetModel } from '../../models/widgets.model';
import { DatasetService } from '../../services/dataset.service';
import { HttpClient, HttpClientModule } from '@angular/common/http';
@Component({
selector: 'app-treemap-widget',
standalone: true,
imports: [CommonModule, TreeMapModule],
providers: [TreeMapTooltipService, TreeMapLegendService, TreeMapHighlightService, TreeMapSelectionService],
imports: [CommonModule, TreeMapModule, HttpClientModule],
providers: [TreeMapTooltipService, TreeMapLegendService, TreeMapHighlightService, TreeMapSelectionService, DatasetService, HttpClient],
templateUrl: './treemap-widget.component.html',
})
export class TreemapWidgetComponent implements OnInit {
export class TreemapWidgetComponent implements OnInit, OnChanges {
@Input() config: any;
@Input() title: string = 'Treemap';
@Input() treemapData: Object[];
......@@ -17,8 +21,10 @@ export class TreemapWidgetComponent implements OnInit {
public weightValuePath: string;
public leafItemSettings: Object;
constructor(private datasetService: DatasetService, private http: HttpClient) { }
ngOnInit(): void {
if (!this.treemapData) {
if (!this.config || !this.config.datasetId) {
this.treemapData = [
{ Continent: 'Asia', Countries: 'China', population: 1400 },
{ Continent: 'Asia', Countries: 'India', population: 1350 },
......@@ -32,4 +38,50 @@ export class TreemapWidgetComponent implements OnInit {
this.weightValuePath = 'population';
this.leafItemSettings = { labelPath: 'Countries' };
}
ngOnChanges(changes: SimpleChanges): void {
if (changes['config'] && this.config && this.config.datasetId) {
this.loadData();
} else if (changes['config'] && (!this.config || !this.config.datasetId)) {
this.treemapData = [
{ Continent: 'Asia', Countries: 'China', population: 1400 },
{ Continent: 'Asia', Countries: 'India', population: 1350 },
{ Continent: 'Europe', Countries: 'Germany', population: 83 },
{ Continent: 'Europe', Countries: 'France', population: 67 },
{ Continent: 'North America', Countries: 'USA', population: 330 },
{ Continent: 'North America', Countries: 'Canada', population: 38 },
];
this.dataSource = this.treemapData;
}
}
loadData(): void {
if (this.config.datasetId) {
this.datasetService.getDatasetById(this.config.datasetId).subscribe((dataset: DatasetModel | undefined) => {
if (dataset && dataset.url) {
this.http.get<any[]>(dataset.url).subscribe(data => {
// Transform data for treemap
// Assuming config.groupField, config.subGroupField, config.valueField
const transformedData = data.map(item => ({
group: item[this.config.groupField],
subGroup: item[this.config.subGroupField],
value: item[this.config.valueField]
}));
this.treemapData = transformedData;
this.dataSource = this.treemapData;
if (this.config.title) {
this.title = this.config.title;
}
if (this.config.groupField) {
this.leafItemSettings = { labelPath: this.config.groupField };
}
if (this.config.valueField) {
this.weightValuePath = this.config.valueField;
}
});
}
});
}
}
}
<ejs-chart [title]="title" [primaryXAxis]="primaryXAxis" [primaryYAxis]="primaryYAxis">
<e-series-collection>
<e-series [dataSource]="chartData" type="Waterfall" xName="category" yName="amount" name="Amount"></e-series>
<e-series [dataSource]="chartData" type="Waterfall" xName="x" yName="y" name="Amount"></e-series>
</e-series-collection>
</ejs-chart>
import { Component, Input, OnInit } from '@angular/core';
import { Component, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ChartModule, WaterfallSeriesService, CategoryService, LegendService, TooltipService, DataLabelService } from '@syncfusion/ej2-angular-charts';
import { DatasetModel } from '../../models/widgets.model';
import { DatasetService } from '../../services/dataset.service';
import { HttpClient, HttpClientModule } from '@angular/common/http';
@Component({
selector: 'app-waterfall-chart-widget',
standalone: true,
imports: [CommonModule, ChartModule],
providers: [WaterfallSeriesService, CategoryService, LegendService, TooltipService, DataLabelService],
imports: [CommonModule, ChartModule, HttpClientModule],
providers: [WaterfallSeriesService, CategoryService, LegendService, TooltipService, DataLabelService, DatasetService, HttpClient],
templateUrl: './waterfall-chart-widget.component.html',
})
export class WaterfallChartWidgetComponent implements OnInit {
@Input() chartData: Object[];
@Input() title: string = 'Waterfall Chart';
export class WaterfallChartWidgetComponent implements OnInit, OnChanges {
@Input() config: any;
public chartData: Object[];
public title: string = 'Waterfall Chart';
public primaryXAxis: Object;
public primaryYAxis: Object;
constructor(private datasetService: DatasetService, private http: HttpClient) { }
ngOnInit(): void {
this.primaryXAxis = { valueType: 'Category', title: 'Category' };
this.primaryYAxis = { title: 'Amount' };
if (!this.chartData) {
if (!this.config || !this.config.datasetId) {
this.chartData = [
{ category: 'Starting Balance', amount: 10000 },
{ category: 'Revenue', amount: 5000 },
......@@ -29,4 +36,39 @@ export class WaterfallChartWidgetComponent implements OnInit {
];
}
}
ngOnChanges(changes: SimpleChanges): void {
if (changes['config'] && this.config && this.config.datasetId) {
this.loadData();
} else if (changes['config'] && (!this.config || !this.config.datasetId)) {
this.chartData = [
{ category: 'Starting Balance', amount: 10000 },
{ category: 'Revenue', amount: 5000 },
{ category: 'Expenses', amount: -2000 },
{ category: 'Investments', amount: 3000 },
{ category: 'Ending Balance', amount: 16000 },
];
}
}
loadData(): void {
if (this.config.datasetId) {
this.datasetService.getDatasetById(this.config.datasetId).subscribe((dataset: DatasetModel | undefined) => {
if (dataset && dataset.url) {
this.http.get<any[]>(dataset.url).subscribe(data => {
this.chartData = data.map(item => ({ x: item[this.config.xField], y: item[this.config.yField] }));
if (this.config.title) {
this.title = this.config.title;
}
if (this.config.xAxisTitle) {
this.primaryXAxis = { ...this.primaryXAxis, title: this.config.xAxisTitle };
}
if (this.config.yAxisTitle) {
this.primaryYAxis = { ...this.primaryYAxis, title: this.config.yAxisTitle };
}
});
}
});
}
}
}
<div class="bg-gradient-to-r from-indigo-500 to-purple-600 p-6 rounded-lg shadow-md text-white flex flex-col justify-center items-center h-full text-center">
<h2 class="text-3xl font-bold mb-2">{{ welcomeMessage }}</h2>
<p class="text-lg">Have a productive day!</p>
<div class="card h-100">
<div class="card-body flex flex-col justify-center items-center">
<h3 class="text-2xl font-bold text-gray-800">{{ welcomeMessage }}</h3>
</div>
</div>
import { Component, Input, OnInit } from '@angular/core';
import { Component, Input, OnInit, SimpleChanges } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MockDataService } from '../../common/mock-data.service';
import { DatasetService } from '../../services/dataset.service';
import { HttpClient } from '@angular/common/http';
import { DatasetModel } from '../../models/widgets.model';
@Component({
selector: 'app-welcome-widget',
......@@ -9,12 +12,39 @@ import { MockDataService } from '../../common/mock-data.service';
templateUrl: './welcome-widget.component.html',
})
export class WelcomeWidgetComponent implements OnInit {
@Input() config: any;
@Input() userName: string = 'Admin'; // New input property
welcomeMessage: string = '';
constructor(private mockDataService: MockDataService) { }
constructor(private datasetService: DatasetService, private http: HttpClient) { }
ngOnInit(): void {
this.welcomeMessage = this.mockDataService.getWelcomeMessage(this.userName);
if (!this.config || !this.config.datasetId) {
this.welcomeMessage = 'Welcome, Admin!';
}
}
ngOnChanges(changes: SimpleChanges): void {
if (changes['config'] && this.config && this.config.datasetId) {
this.loadData();
} else if (changes['config'] && (!this.config || !this.config.datasetId)) {
this.welcomeMessage = 'Welcome, Admin!';
}
}
loadData(): void {
if (this.config.datasetId) {
this.datasetService.getDatasetById(this.config.datasetId).subscribe((dataset: DatasetModel | undefined) => {
if (dataset && dataset.url) {
this.http.get<any[]>(dataset.url).subscribe(data => {
if (data.length > 0 && this.config.messageField) {
this.welcomeMessage = data[0][this.config.messageField];
} else {
this.welcomeMessage = 'Welcome, Admin!';
}
});
}
});
}
}
}
......@@ -21,11 +21,6 @@ import { AuthService } from './services/auth.service';
import { TranslateModule } from '@ngx-translate/core';
import { RenderedHtmlComponent } from '../components/rendered-html/rendered-html.component';
import { QuillModule } from 'ngx-quill';
import { CompanyInfoWidgetComponent } from '../DPU/widgets/company-info-widget/company-info-widget.component';
import { TimeTrackingWidgetComponent } from '../DPU/widgets/time-tracking-widget/time-tracking-widget.component';
import { PayrollWidgetComponent } from '../DPU/widgets/payroll-widget/payroll-widget.component';
import { EmployeeDirectoryWidgetComponent } from '../DPU/widgets/employee-directory-widget/employee-directory-widget.component';
@NgModule({
declarations: [
......@@ -41,11 +36,7 @@ import { EmployeeDirectoryWidgetComponent } from '../DPU/widgets/employee-direct
AuthenticationLayoutComponent,
LandingSwitcherComponent,
LandingLayoutComponent,
RenderedHtmlComponent,
CompanyInfoWidgetComponent,
TimeTrackingWidgetComponent,
PayrollWidgetComponent,
EmployeeDirectoryWidgetComponent
RenderedHtmlComponent
],
imports: [
......@@ -72,11 +63,7 @@ import { EmployeeDirectoryWidgetComponent } from '../DPU/widgets/employee-direct
AuthenticationLayoutComponent,
LandingSwitcherComponent,
LandingLayoutComponent,
RenderedHtmlComponent,
CompanyInfoWidgetComponent,
TimeTrackingWidgetComponent,
PayrollWidgetComponent,
EmployeeDirectoryWidgetComponent
RenderedHtmlComponent
],
providers: [ColorPickerService, AuthService , TranslateModule],
})
......
[
{ "month": "Jan", "sales": 35 },
{ "month": "Feb", "sales": 28 },
{ "month": "Mar", "sales": 34 },
{ "month": "Apr", "sales": 32 },
{ "month": "May", "sales": 40 },
{ "month": "Jun", "sales": 30 },
{ "month": "Jul", "sales": 35 },
{ "month": "Aug", "sales": 37 },
{ "month": "Sep", "sales": 39 },
{ "month": "Oct", "sales": 30 },
{ "month": "Nov", "sales": 35 },
{ "month": "Dec", "sales": 41 }
]
\ No newline at end of file
[
{ "country": "USA", "sales": 20 },
{ "country": "China", "sales": 25 },
{ "country": "Japan", "sales": 18 },
{ "country": "Germany", "sales": 15 },
{ "country": "France", "sales": 22 },
{ "country": "UK", "sales": 10 }
]
\ No newline at end of file
[
{
"id": "E001",
"name": "Alice Smith",
"department": "Sales",
"salary": 60000,
"hireDate": "2020-01-15",
"performanceScore": 85,
"gender": "Female",
"age": 30,
"salesAmount": 120000,
"region": "North"
},
{
"id": "E002",
"name": "Bob Johnson",
"department": "Marketing",
"salary": 55000,
"hireDate": "2019-03-20",
"performanceScore": 92,
"gender": "Male",
"age": 35,
"salesAmount": 0,
"region": "East"
},
{
"id": "E003",
"name": "Charlie Brown",
"department": "Sales",
"salary": 62000,
"hireDate": "2021-07-01",
"performanceScore": 78,
"gender": "Male",
"age": 28,
"salesAmount": 110000,
"region": "West"
},
{
"id": "E004",
"name": "Diana Prince",
"department": "HR",
"salary": 70000,
"hireDate": "2018-11-10",
"performanceScore": 95,
"gender": "Female",
"age": 40,
"salesAmount": 0,
"region": "South"
},
{
"id": "E005",
"name": "Eve Adams",
"department": "Marketing",
"salary": 58000,
"hireDate": "2022-05-25",
"performanceScore": 88,
"gender": "Female",
"age": 25,
"salesAmount": 0,
"region": "North"
},
{
"id": "E006",
"name": "Frank White",
"department": "Sales",
"salary": 65000,
"hireDate": "2019-09-01",
"performanceScore": 90,
"gender": "Male",
"age": 32,
"salesAmount": 130000,
"region": "East"
}
]
\ No newline at end of file
{
"value": "1,234,567",
"unit": "USD",
"trend": "up",
"trendValue": "+5%"
}
\ No newline at end of file
[
{ "country": "United States", "value": 80 },
{ "country": "Canada", "value": 60 },
{ "country": "Mexico", "value": 40 },
{ "country": "Brazil", "value": 70 },
{ "country": "Argentina", "value": 30 }
]
\ No newline at end of file
[
{ "browser": "Chrome", "users": 37 },
{ "browser": "Firefox", "users": 17 },
{ "browser": "Internet Explorer", "users": 19 },
{ "browser": "Edge", "users": 4 },
{ "browser": "Safari", "users": 11 },
{ "browser": "Other", "users": 12 }
]
\ No newline at end of file
{
"headers": ["ID", "Product", "Quantity", "Price"],
"data": [
[1, "Laptop", 10, 1200],
[2, "Mouse", 50, 25],
[3, "Keyboard", 30, 75],
[4, "Monitor", 5, 300]
]
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment