diff --git a/.github/workflows/ui-charts-ci.yml b/.github/workflows/ui-charts-ci.yml
index 1327cd9f..93cf8f8c 100644
--- a/.github/workflows/ui-charts-ci.yml
+++ b/.github/workflows/ui-charts-ci.yml
@@ -1,4 +1,4 @@
-name: UI CI
+name: UI Charts CI
on:
push:
diff --git a/Plugins/UI/default-scriptbee-charts/federation.config.mjs b/Plugins/UI/default-scriptbee-charts/federation.config.mjs
index b550411d..3d6d970d 100644
--- a/Plugins/UI/default-scriptbee-charts/federation.config.mjs
+++ b/Plugins/UI/default-scriptbee-charts/federation.config.mjs
@@ -2,13 +2,13 @@ import { shareAll, withNativeFederation } from '@angular-architects/native-feder
export default withNativeFederation({
name: 'default-scriptbee-charts',
-
+ exposes: {
+ './BarChart': './src/app/components/bar-chart/bar-chart.ts',
+ },
shared: {
...shareAll({ singleton: true, strictVersion: false, requiredVersion: 'auto' }),
},
-
skip: ['@angular-architects/native-federation', 'rxjs/ajax', 'rxjs/fetch', 'rxjs/testing', 'rxjs/webSocket'],
-
features: {
ignoreUnusedDeps: true,
},
diff --git a/Plugins/UI/default-scriptbee-charts/src/app/app.html b/Plugins/UI/default-scriptbee-charts/src/app/app.html
index 9baf8929..6c35a40f 100644
--- a/Plugins/UI/default-scriptbee-charts/src/app/app.html
+++ b/Plugins/UI/default-scriptbee-charts/src/app/app.html
@@ -1 +1,8 @@
Hello, default-scriptbee-chart!
+
+
+ Mode: {{ themeService.echartsTheme() }}
+
+
+
+
diff --git a/Plugins/UI/default-scriptbee-charts/src/app/app.spec.ts b/Plugins/UI/default-scriptbee-charts/src/app/app.spec.ts
index 75753d68..89efcb0c 100644
--- a/Plugins/UI/default-scriptbee-charts/src/app/app.spec.ts
+++ b/Plugins/UI/default-scriptbee-charts/src/app/app.spec.ts
@@ -1,10 +1,20 @@
+import { computed, signal } from '@angular/core';
import { TestBed } from '@angular/core/testing';
import { App } from './app';
+import { ThemeService } from './services/theme.service';
+
+describe('AppComponent with Mock Theme', () => {
+ let mockThemeService: Partial;
-describe('App', () => {
beforeEach(async () => {
+ mockThemeService = {
+ isDark: signal(false),
+ echartsTheme: computed(() => 'light'),
+ };
+
await TestBed.configureTestingModule({
imports: [App],
+ providers: [{ provide: ThemeService, useValue: mockThemeService }],
}).compileComponents();
});
diff --git a/Plugins/UI/default-scriptbee-charts/src/app/app.ts b/Plugins/UI/default-scriptbee-charts/src/app/app.ts
index 66363352..49febb5d 100644
--- a/Plugins/UI/default-scriptbee-charts/src/app/app.ts
+++ b/Plugins/UI/default-scriptbee-charts/src/app/app.ts
@@ -1,9 +1,67 @@
-import { Component } from '@angular/core';
+import { Component, computed, inject } from '@angular/core';
+import { BarChart } from './components/bar-chart/bar-chart';
+import { ThemeService } from './services/theme.service';
+import { BarChartInput, ChartParameters } from './types/ChartInput';
@Component({
selector: 'app-root',
- imports: [],
+ imports: [BarChart],
templateUrl: './app.html',
styleUrl: './app.scss',
})
-export class App {}
+export class App {
+ readonly themeService = inject(ThemeService);
+
+ barChartParameters = computed>(() => {
+ const xAxisData = [];
+ const data1 = [];
+ const data2 = [];
+ const data3 = [];
+
+ for (let i = 0; i < 100; i++) {
+ xAxisData.push('category' + i);
+ data1.push((Math.sin(i / 5) * (i / 5 - 10) + i / 6) * 5);
+ data2.push((Math.cos(i / 5) * (i / 5 - 10) + i / 6) * 5);
+ data3.push((Math.sin(i / 5) * (i / 5 + 10) + i / 6) * 5);
+ }
+
+ const series: ChartParameters['input']['series'] = [
+ {
+ name: 'bar',
+ data: data1,
+ },
+ {
+ name: 'bar2',
+ data: data2,
+ },
+ {
+ name: 'bar3',
+ data: data3,
+ color: 'red',
+ },
+ ];
+
+ return {
+ theme: this.themeService.echartsTheme(),
+ input: {
+ xAxis: {
+ data: xAxisData,
+ silent: false,
+ splitLine: {
+ show: false,
+ },
+ },
+ yAxis: {},
+ legend: {
+ data: ['bar', 'bar2', 'bar3'],
+ align: 'left',
+ },
+ tooltip: {},
+ series: series,
+ options: {
+ animationEasing: 'elasticOut',
+ },
+ },
+ };
+ });
+}
diff --git a/Plugins/UI/default-scriptbee-charts/src/app/components/bar-chart/bar-chart.html b/Plugins/UI/default-scriptbee-charts/src/app/components/bar-chart/bar-chart.html
new file mode 100644
index 00000000..bf3048e2
--- /dev/null
+++ b/Plugins/UI/default-scriptbee-charts/src/app/components/bar-chart/bar-chart.html
@@ -0,0 +1 @@
+
diff --git a/Plugins/UI/default-scriptbee-charts/src/app/components/bar-chart/bar-chart.scss b/Plugins/UI/default-scriptbee-charts/src/app/components/bar-chart/bar-chart.scss
new file mode 100644
index 00000000..e69de29b
diff --git a/Plugins/UI/default-scriptbee-charts/src/app/components/bar-chart/bar-chart.ts b/Plugins/UI/default-scriptbee-charts/src/app/components/bar-chart/bar-chart.ts
new file mode 100644
index 00000000..fd8a5b5e
--- /dev/null
+++ b/Plugins/UI/default-scriptbee-charts/src/app/components/bar-chart/bar-chart.ts
@@ -0,0 +1,34 @@
+import { Component, computed, input } from '@angular/core';
+import { EChartsCoreOption } from 'echarts';
+import { NgxEchartsDirective, provideEchartsCore } from 'ngx-echarts';
+import * as echarts from 'echarts/core';
+import { BarChart as EchartsBarChart } from 'echarts/charts';
+import { GridComponent, LegendComponent, TooltipComponent } from 'echarts/components';
+import { CanvasRenderer } from 'echarts/renderers';
+import { BarChartInput, ChartParameters } from '../../types/ChartInput';
+
+echarts.use([EchartsBarChart, GridComponent, CanvasRenderer, LegendComponent, TooltipComponent]);
+
+@Component({
+ selector: 'app-bar-chart',
+ imports: [NgxEchartsDirective],
+ templateUrl: './bar-chart.html',
+ styleUrl: './bar-chart.scss',
+ providers: [provideEchartsCore({ echarts })],
+})
+export class BarChart {
+ parameters = input.required>();
+
+ options = computed(() => {
+ const input = this.parameters().input;
+
+ return {
+ ...(input.options ?? {}),
+ legend: input.legend,
+ tooltip: input.tooltip,
+ xAxis: input.xAxis,
+ yAxis: input.yAxis,
+ series: (input.series ?? []).map((s) => ({ ...s, type: 'bar' })),
+ };
+ });
+}
diff --git a/Plugins/UI/default-scriptbee-charts/src/app/services/theme.service.ts b/Plugins/UI/default-scriptbee-charts/src/app/services/theme.service.ts
new file mode 100644
index 00000000..35820d4f
--- /dev/null
+++ b/Plugins/UI/default-scriptbee-charts/src/app/services/theme.service.ts
@@ -0,0 +1,40 @@
+import { Injectable, signal, computed } from '@angular/core';
+
+@Injectable({ providedIn: 'root' })
+export class ThemeService {
+ private readonly STORAGE_KEY = 'ngx-echarts-theme';
+
+ readonly isDark = signal(this.loadTheme());
+
+ readonly echartsTheme = computed(() => (this.isDark() ? 'dark' : 'light'));
+
+ constructor() {
+ this.applyTheme(this.isDark());
+ }
+
+ toggle(): void {
+ const dark = !this.isDark();
+ this.isDark.set(dark);
+ this.applyTheme(dark);
+ localStorage.setItem(this.STORAGE_KEY, dark ? 'dark' : 'light');
+ }
+
+ private loadTheme(): boolean {
+ const stored = localStorage.getItem(this.STORAGE_KEY);
+ if (stored) {
+ return stored === 'dark';
+ }
+ return window.matchMedia('(prefers-color-scheme: dark)').matches;
+ }
+
+ private applyTheme(dark: boolean): void {
+ const body = document.body;
+ if (dark) {
+ body.classList.add('dark-theme');
+ body.classList.remove('light-theme');
+ } else {
+ body.classList.add('light-theme');
+ body.classList.remove('dark-theme');
+ }
+ }
+}
diff --git a/Plugins/UI/default-scriptbee-charts/src/app/types/ChartInput.ts b/Plugins/UI/default-scriptbee-charts/src/app/types/ChartInput.ts
new file mode 100644
index 00000000..4b067498
--- /dev/null
+++ b/Plugins/UI/default-scriptbee-charts/src/app/types/ChartInput.ts
@@ -0,0 +1,19 @@
+import { EChartsCoreOption } from 'echarts/types/dist/echarts';
+import { EChartsOption } from 'echarts/types/dist/shared';
+import { BarSeriesOption } from 'echarts';
+
+export type Theme = 'light' | 'dark';
+
+export interface ChartParameters {
+ theme: Theme;
+ input: T;
+}
+
+export interface BarChartInput {
+ xAxis: EChartsOption['xAxis'];
+ yAxis: EChartsOption['yAxis'];
+ legend: EChartsOption['legend'];
+ tooltip: EChartsOption['tooltip'];
+ series: Omit[];
+ options?: EChartsCoreOption;
+}