@sisense/sdk-ui-angular 2.17.0 → 2.18.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/dist/esm2020/lib/components/charts/pivot-table.component.mjs +21 -3
  2. package/dist/esm2020/lib/components/widgets/pivot-table-widget.component.mjs +24 -3
  3. package/dist/esm2020/lib/components/widgets/widget.component.mjs +1 -1
  4. package/dist/esm2020/lib/decorators/decorators.module.mjs +2 -2
  5. package/dist/esm2020/lib/helpers/dashboard-props-preact-translator.mjs +1 -1
  6. package/dist/esm2020/lib/helpers/widget-props-preact-translator.mjs +5 -2
  7. package/dist/esm2020/lib/sdk-ui-core-exports.mjs +1 -1
  8. package/dist/esm2020/lib/services/dashboard.service.mjs +18 -6
  9. package/dist/esm2020/lib/services/widget.service.mjs +146 -6
  10. package/dist/esm2020/lib/types/chart-event-props.mjs +1 -1
  11. package/dist/esm2020/lib/types/data-point.mjs +1 -1
  12. package/dist/esm2020/lib/utilities/widget-model-translator.mjs +52 -1
  13. package/dist/esm2020/public-api.mjs +1 -1
  14. package/dist/esm2020/version.mjs +2 -2
  15. package/dist/fesm2015/sisense-sdk-ui-angular.mjs +1566 -1324
  16. package/dist/fesm2015/sisense-sdk-ui-angular.mjs.map +1 -1
  17. package/dist/fesm2020/sisense-sdk-ui-angular.mjs +1372 -1130
  18. package/dist/fesm2020/sisense-sdk-ui-angular.mjs.map +1 -1
  19. package/dist/lib/components/charts/pivot-table.component.d.ts +16 -3
  20. package/dist/lib/components/widgets/pivot-table-widget.component.d.ts +22 -3
  21. package/dist/lib/components/widgets/widget.component.d.ts +8 -4
  22. package/dist/lib/decorators/decorators.module.d.ts +1 -1
  23. package/dist/lib/helpers/dashboard-props-preact-translator.d.ts +1 -1
  24. package/dist/lib/helpers/widget-props-preact-translator.d.ts +1 -1
  25. package/dist/lib/sdk-ui-core-exports.d.ts +1 -1
  26. package/dist/lib/services/dashboard.service.d.ts +13 -5
  27. package/dist/lib/services/widget.service.d.ts +100 -2
  28. package/dist/lib/types/chart-event-props.d.ts +15 -1
  29. package/dist/lib/types/data-point.d.ts +13 -2
  30. package/dist/lib/utilities/widget-model-translator.d.ts +50 -1
  31. package/dist/package.json +1 -1
  32. package/dist/public-api.d.ts +1 -1
  33. package/dist/version.d.ts +1 -1
  34. package/package.json +4 -4
@@ -1,6 +1,6 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, Injectable, Optional, Inject, createComponent, NgModule, EventEmitter, Component, ViewChild, Input, Output } from '@angular/core';
3
- import { DataObserver, CustomThemeProvider, CustomSisenseContextProvider, CustomWidgetsProviderAdapter, createClientApplication, TabberButtonsWidget, createWrapperElement, getDashboardModel, getDashboardModels, HookAdapter, useComposedDashboardInternal, createHookApiFacade, useGetFilterMembers, getHierarchyModels, executeQuery, executeQueryByWidgetId, executePivotQuery, useExecuteCsvQueryInternal, useExecuteCustomWidgetQueryInternal, getWidgetModel, getDefaultThemeSettings, getThemeSettingsByOid, ComponentAdapter, Chart, PivotTable, Table, ContextMenu, Dashboard, DashboardById, DrilldownBreadcrumbs, CriteriaFilterTile, DateRangeFilterTile, FilterTile, FiltersPanel, MemberFilterTile, RelativeDateFilterTile, ChartWidget, DrilldownWidget, createWrapperElementHandler, createComponentRenderer, PivotTableWidget, TableWidget, Widget, WidgetById, dashboardModelTranslator as dashboardModelTranslator$1, dashboardHelpers as dashboardHelpers$1, widgetModelTranslator as widgetModelTranslator$1 } from '@sisense/sdk-ui-preact';
2
+ import { InjectionToken, Injectable, Optional, Inject, NgModule, EventEmitter, Component, ViewChild, Input, Output, createComponent } from '@angular/core';
3
+ import { DataObserver, CustomThemeProvider, CustomSisenseContextProvider, CustomWidgetsProviderAdapter, createClientApplication, getDefaultThemeSettings, getThemeSettingsByOid, ComponentAdapter, Chart, TabberButtonsWidget, createWrapperElement, getDashboardModel, getDashboardModels, HookAdapter, useComposedDashboardInternal, createHookApiFacade, useGetFilterMembers, getHierarchyModels, executeQuery, executeQueryByWidgetId, executePivotQuery, useExecuteCsvQueryInternal, useExecuteCustomWidgetQueryInternal, getWidgetModel, useJtdWidget, PivotTable, Table, ContextMenu, Dashboard, DashboardById, DrilldownBreadcrumbs, CriteriaFilterTile, DateRangeFilterTile, FilterTile, FiltersPanel, MemberFilterTile, RelativeDateFilterTile, ChartWidget, DrilldownWidget, createWrapperElementHandler, createComponentRenderer, PivotTableWidget, TableWidget, Widget, WidgetById, dashboardModelTranslator as dashboardModelTranslator$1, dashboardHelpers as dashboardHelpers$1, widgetModelTranslator as widgetModelTranslator$1 } from '@sisense/sdk-ui-preact';
4
4
  export { boxWhiskerProcessResult, extractDimensionsAndMeasures } from '@sisense/sdk-ui-preact';
5
5
  import { ReplaySubject, firstValueFrom, concat, of, BehaviorSubject, skip } from 'rxjs';
6
6
  import { __decorate } from 'tslib';
@@ -285,915 +285,499 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
285
285
  args: [SISENSE_CONTEXT_CONFIG_TOKEN]
286
286
  }] }]; } });
287
287
 
288
- var packageVersion = '2.17.0';
288
+ var packageVersion = '2.18.1';
289
289
 
290
- /**
291
- * Service for rendering components dynamically.
292
- *
293
- * @internal
294
- */
295
- class DynamicRenderer {
296
- constructor(appRef, injector, envInjector) {
297
- this.appRef = appRef;
298
- this.injector = injector;
299
- this.envInjector = envInjector;
300
- }
301
- renderComponent(component, props) {
302
- const componentRef = createComponent(component, {
303
- environmentInjector: this.envInjector,
304
- elementInjector: this.injector,
305
- });
306
- // Apply props to the component instance
307
- Object.assign(componentRef.instance, props);
308
- // Attach the component to the application
309
- this.appRef.attachView(componentRef.hostView);
310
- // Get the DOM element
311
- const domElem = componentRef.hostView.rootNodes[0];
312
- // Create destroy function
313
- const destroy = () => {
314
- // Detach from application
315
- this.appRef.detachView(componentRef.hostView);
316
- // Destroy the component
317
- componentRef.destroy();
318
- };
319
- return {
320
- element: domElem,
321
- componentRef,
322
- destroy,
323
- };
324
- }
325
- }
326
- DynamicRenderer.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DynamicRenderer, deps: [{ token: i0.ApplicationRef }, { token: i0.Injector }, { token: i0.EnvironmentInjector }], target: i0.ɵɵFactoryTarget.Injectable });
327
- DynamicRenderer.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DynamicRenderer, providedIn: 'root' });
328
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DynamicRenderer, decorators: [{
329
- type: Injectable,
330
- args: [{ providedIn: 'root' }]
331
- }], ctorParameters: function () { return [{ type: i0.ApplicationRef }, { type: i0.Injector }, { type: i0.EnvironmentInjector }]; } });
332
-
333
- /**
334
- * Service for working with custom widgets.
335
- *
336
- * @group Dashboards
337
- */
338
- class CustomWidgetsService {
339
- constructor(
340
- /** @internal */
341
- dynamicRenderer) {
342
- this.dynamicRenderer = dynamicRenderer;
343
- this.customWidgetsMap$ = new BehaviorSubject(new Map([['tabber-buttons', TabberButtonsWidget]]));
344
- }
345
- /**
346
- * Registers a new custom widget.
347
- *
348
- * @param customWidgetType - The unique identifier for the custom widget type.
349
- * @param customWidget - The custom widget component class to register.
350
- */
351
- registerCustomWidget(customWidgetType, customWidget) {
352
- const customWidgetPreactComponent = (props) => {
353
- const renderedComponent = this.dynamicRenderer.renderComponent(customWidget, props);
354
- return createWrapperElement(renderedComponent.element, () => renderedComponent.destroy());
355
- };
356
- const customWidgetsMap = this.customWidgetsMap$.value;
357
- if (!customWidgetsMap.has(customWidgetType)) {
358
- customWidgetsMap.set(customWidgetType, customWidgetPreactComponent);
359
- this.customWidgetsMap$.next(customWidgetsMap);
360
- }
361
- }
362
- /**
363
- * Checks if a custom widget is registered.
364
- *
365
- * @param customWidgetType - The type of the custom widget.
366
- * @returns True if the custom widget is registered, false otherwise.
367
- */
368
- hasCustomWidget(customWidgetType) {
369
- return this.customWidgetsMap$.value.has(customWidgetType);
290
+ class DecoratorsModule {
291
+ constructor(sisenseContextService) {
292
+ DecoratorsModule.sisenseContextService = sisenseContextService;
370
293
  }
371
294
  }
372
- CustomWidgetsService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: CustomWidgetsService, deps: [{ token: DynamicRenderer }], target: i0.ɵɵFactoryTarget.Injectable });
373
- CustomWidgetsServiceprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: CustomWidgetsService, providedIn: 'root' });
374
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: CustomWidgetsService, decorators: [{
375
- type: Injectable,
295
+ DecoratorsModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DecoratorsModule, deps: [{ token: SisenseContextService }], target: i0.ɵɵFactoryTarget.NgModule });
296
+ DecoratorsModulemod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.10", ngImport: i0, type: DecoratorsModule });
297
+ DecoratorsModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DecoratorsModule });
298
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DecoratorsModule, decorators: [{
299
+ type: NgModule,
376
300
  args: [{
377
- providedIn: 'root',
301
+ declarations: [],
302
+ exports: [],
378
303
  }]
379
- }], ctorParameters: function () { return [{ type: DynamicRenderer }]; } });
304
+ }], ctorParameters: function () { return [{ type: SisenseContextService }]; } });
380
305
 
381
- function translateToPreactWidgetProps(widgetProps) {
382
- const { beforeRender, dataReady, beforeMenuOpen, dataPointClick, dataPointContextMenu, dataPointsSelect, ...commonWidgetProps } = widgetProps;
383
- return {
384
- ...commonWidgetProps,
385
- onBeforeRender: beforeRender,
386
- onDataReady: dataReady,
387
- onBeforeMenuOpen: beforeMenuOpen,
388
- onDataPointClick: dataPointClick
389
- ? (...[point, nativeEvent]) => dataPointClick({
390
- point,
391
- nativeEvent,
392
- })
393
- : undefined,
394
- onDataPointContextMenu: dataPointContextMenu
395
- ? (...[point, nativeEvent]) => dataPointContextMenu({ point, nativeEvent })
396
- : undefined,
397
- onDataPointsSelected: dataPointsSelect
398
- ? (...[points, nativeEvent]) => dataPointsSelect({ points, nativeEvent })
399
- : undefined,
400
- };
401
- }
402
- function translateFromPreactWidgetProps(widgetProps) {
403
- const { onBeforeRender, onDataReady, onBeforeMenuOpen, onDataPointClick, onDataPointContextMenu, onDataPointsSelected, ...commonWidgetProps } = widgetProps;
404
- return {
405
- ...commonWidgetProps,
406
- beforeRender: onBeforeRender,
407
- dataReady: onDataReady,
408
- beforeMenuOpen: onBeforeMenuOpen,
409
- dataPointClick: onDataPointClick
410
- ? ({ point, nativeEvent }) => onDataPointClick(point, nativeEvent)
411
- : undefined,
412
- dataPointContextMenu: onDataPointContextMenu
413
- ? ({ point, nativeEvent }) => onDataPointContextMenu(point, nativeEvent)
414
- : undefined,
415
- dataPointsSelect: onDataPointsSelected
416
- ? ({ points, nativeEvent }) => onDataPointsSelected(points, nativeEvent)
417
- : undefined,
306
+ function Trackable(target, propertyKey, descriptor) {
307
+ const originalMethod = descriptor.value;
308
+ descriptor.value = function (...args) {
309
+ track('sdkAngularServiceMethodExecuted', propertyKey);
310
+ return originalMethod.apply(this, args);
418
311
  };
312
+ return descriptor;
419
313
  }
420
-
421
- function translateToPreactDashboardProps(dashboardProps) {
422
- return {
423
- ...dashboardProps,
424
- widgets: dashboardProps.widgets.map(translateToPreactWidgetProps),
314
+ /** @internal */
315
+ function TrackableService(trackableMethods) {
316
+ return function (ServiceClass) {
317
+ trackableMethods.forEach((methodName) => {
318
+ // eslint-disable-next-line security/detect-object-injection
319
+ const original = ServiceClass.prototype[methodName];
320
+ // eslint-disable-next-line security/detect-object-injection
321
+ ServiceClass.prototype[methodName] = function (...params) {
322
+ track('sdkAngularServiceMethodExecuted', `${ServiceClass.name}.${methodName}`);
323
+ return original.apply(this, params);
324
+ };
325
+ });
425
326
  };
426
327
  }
427
- function translateFromPreactDashboardProps(dashboardProps) {
428
- return {
429
- ...dashboardProps,
430
- widgets: dashboardProps.widgets.map(translateFromPreactWidgetProps),
431
- };
328
+ async function track(action, methodName) {
329
+ try {
330
+ const app = await DecoratorsModule.sisenseContextService.getApp();
331
+ const trackingEnabled = app.settings?.trackingConfig?.enabled ?? true;
332
+ if (app?.httpClient) {
333
+ const payload = {
334
+ packageName: 'sdk-ui-angular',
335
+ packageVersion,
336
+ methodName,
337
+ };
338
+ void trackProductEvent(action, payload, app.httpClient, !trackingEnabled);
339
+ }
340
+ }
341
+ catch (e) {
342
+ console.warn('tracking error', e);
343
+ }
432
344
  }
433
345
 
434
346
  /**
435
- * Service for working with Sisense Fusion dashboards.
347
+ * Token used to inject {@link ThemeConfig} into your application
436
348
  *
437
- * **Note:** Dashboard and Widget extensions based on JS scripts and add-ons in Fusion – for example, Blox and Jump To Dashboard – are not supported.
349
+ * @example
438
350
  *
439
- * @group Fusion Assets
440
- * @fusionEmbed
351
+ * Example of injecting both {@link SisenseContextConfig} and {@link ThemeConfig} into your application:
352
+ *
353
+ * ```ts
354
+ * export const SISENSE_CONTEXT_CONFIG: SisenseContextConfig = {
355
+ * url: "<instance url>", // replace with the URL of your Sisense instance
356
+ * token: "<api token>", // replace with the API token of your user account
357
+ * defaultDataSource: DM.DataSource,
358
+ * };
359
+ *
360
+ * @NgModule({
361
+ * imports: [
362
+ * BrowserModule,
363
+ * SdkUiModule,
364
+ * ],
365
+ * declarations: [AppComponent],
366
+ * providers: [
367
+ * { provide: SISENSE_CONTEXT_CONFIG_TOKEN, useValue: SISENSE_CONTEXT_CONFIG },
368
+ * {
369
+ * provide: THEME_CONFIG_TOKEN,
370
+ * useValue: {
371
+ * // initial theme settings
372
+ * } as ThemeConfig,
373
+ * },
374
+ * ],
375
+ * bootstrap: [AppComponent],
376
+ * })
377
+ * ```
378
+ * @group Contexts
441
379
  */
442
- let DashboardService = class DashboardService {
443
- constructor(sisenseContextService) {
380
+ const THEME_CONFIG_TOKEN = new InjectionToken('theme configuration');
381
+ /**
382
+ * Service for working with Sisense Fusion themes.
383
+ *
384
+ * If no theme service is used, the current Fusion theme is applied by default.
385
+ *
386
+ * @group Contexts
387
+ */
388
+ let ThemeService = class ThemeService {
389
+ constructor(sisenseContextService, themeConfig) {
444
390
  this.sisenseContextService = sisenseContextService;
391
+ this.initializationPromise = Promise.resolve();
392
+ this.themeSettings$ = new BehaviorSubject(getDefaultThemeSettings());
393
+ this.initializationPromise = this.initThemeSettings(themeConfig?.theme);
394
+ this.sisenseContextService
395
+ .getApp$()
396
+ // Skip current app value
397
+ .pipe(skip(1))
398
+ // Subscribe to new app values
399
+ .subscribe({
400
+ next: ({ app }) => {
401
+ if (app) {
402
+ this.initializationPromise = this.applyThemeSettings(app.settings.serverThemeSettings);
403
+ }
404
+ },
405
+ });
445
406
  }
446
- /**
447
- * Retrieves an existing dashboard model from the Sisense instance.
448
- *
449
- * @param dashboardOid - Identifier of the dashboard
450
- * @param options - Advanced configuration options
451
- * @returns Dashboard model
452
- */
453
- async getDashboardModel(dashboardOid, options) {
407
+ async initThemeSettings(theme) {
454
408
  const app = await this.sisenseContextService.getApp();
455
- return getDashboardModel(app.httpClient, dashboardOid, options);
409
+ // apply system theme settings first
410
+ await this.applyThemeSettings(app.settings.serverThemeSettings);
411
+ if (theme) {
412
+ // Manually tracks theme update during initialization as execution of updateThemeSettings for consistency.
413
+ track('sdkAngularServiceMethodExecuted', 'ThemeService.updateThemeSettings');
414
+ await this.applyThemeSettings(theme);
415
+ }
456
416
  }
457
- /**
458
- * Retrieves existing dashboard models from the Sisense instance.
459
- *
460
- * @param options - Advanced configuration options
461
- * @returns Dashboard models array
462
- */
463
- async getDashboardModels(options) {
464
- const app = await this.sisenseContextService.getApp();
465
- return getDashboardModels(app.httpClient, options);
466
- }
467
- /**
468
- * Сomposes dashboard or separate dashboard elements into a coordinated dashboard
469
- * with cross filtering, and change detection.
470
- *
471
- * @example
472
- * An example of using the `createComposedDashboard` to construct a composed dashboard and render it:
473
- * ```html
474
- <!--Component HTML template in example.component.html-->
475
- <div *ngIf="dashboard$ | async as dashboard">
476
- <csdk-filter-tile
477
- *ngFor="let filter of getDashboardFilters(dashboard); trackBy: trackByIndex"
478
- [filter]="filter"
479
- />
480
- <csdk-widget
481
- *ngFor="let widget of dashboard.widgets; trackBy: trackByIndex"
482
- [id]="widget.id"
483
- [widgetType]="widget.widgetType"
484
- [chartType]="widget.chartType"
485
- [customWidgetType]="widget.customWidgetType"
486
- [dataSource]="widget.dataSource"
487
- [dataOptions]="widget.dataOptions"
488
- [filters]="widget.filters"
489
- [highlights]="widget.highlights"
490
- [styleOptions]="widget.styleOptions"
491
- [drilldownOptions]="widget.drilldownOptions"
492
- [title]="widget.title"
493
- [description]="widget.description"
494
- [beforeMenuOpen]="widget.beforeMenuOpen"
495
- (dataPointClick)="widget.dataPointClick?.($event)"
496
- (dataPointContextMenu)="widget.dataPointContextMenu?.($event)"
497
- (dataPointsSelect)="widget.dataPointsSelect?.($event)"
498
- />
499
- </div>
500
- * ```
501
- *
502
- * ```ts
503
- // Component behavior in example.component.ts
504
- import { Component } from '@angular/core';
505
- import { BehaviorSubject } from 'rxjs';
506
- import { DashboardService, type DashboardProps } from '@sisense/sdk-ui-angular';
507
-
508
- @Component({
509
- selector: 'example',
510
- templateUrl: './example.component.html',
511
- styleUrls: ['./example.component.scss'],
512
- })
513
- export class ExampleComponent {
514
- dashboard$: BehaviorSubject<DashboardProps> | undefined;
515
-
516
- constructor(private dashboardService: DashboardService) {}
517
-
518
- ngOnInit() {
519
- const initialDashboard: DashboardProps = { ... };
520
- const composedDashboard = this.dashboardService.createComposedDashboard(initialDashboard);
521
- this.dashboard$ = composedDashboard.dashboard$;
417
+ async applyThemeSettings(theme) {
418
+ try {
419
+ const app = await this.sisenseContextService.getApp();
420
+ const isThemeOid = typeof theme === 'string';
421
+ let userThemeSettings = theme;
422
+ if (isThemeOid) {
423
+ userThemeSettings = await getThemeSettingsByOid(theme, app.httpClient);
424
+ }
425
+ const mergedThemeSettings = merge.withOptions({ mergeArrays: false }, this.themeSettings$.value, userThemeSettings);
426
+ this.themeSettings$.next(mergedThemeSettings);
427
+ }
428
+ catch (error) {
429
+ this.themeSettings$.error(error);
522
430
  }
523
-
524
- trackByIndex = (index: number) => index;
525
-
526
- getDashboardFilters = ({ filters }: DashboardProps) => Array.isArray(filters) ? filters : [];
527
- }
528
- * ```
529
- * @param initialDashboard - Initial dashboard
530
- * @param options - Configuration options
531
- * @returns Reactive composed dashboard object and API methods for interacting with it
532
- */
533
- createComposedDashboard(initialDashboard, options = {}) {
534
- const hookAdapter = new HookAdapter((useComposedDashboardInternal), [createSisenseContextConnector(this.sisenseContextService)]);
535
- const dashboard$ = new BehaviorSubject(initialDashboard);
536
- hookAdapter.subscribe(({ dashboard }) => {
537
- dashboard$.next(translateFromPreactDashboardProps(dashboard));
538
- });
539
- hookAdapter.run(translateToPreactDashboardProps(initialDashboard), options);
540
- const setFilters = createHookApiFacade(hookAdapter, 'setFilters', true);
541
- const setWidgetsLayout = createHookApiFacade(hookAdapter, 'setWidgetsLayout', true);
542
- return {
543
- dashboard$,
544
- setFilters,
545
- setWidgetsLayout,
546
- };
431
+ }
432
+ /** @internal */
433
+ getThemeSettings() {
434
+ return this.themeSettings$.asObservable();
435
+ }
436
+ async updateThemeSettings(theme) {
437
+ await this.initializationPromise;
438
+ await this.applyThemeSettings(theme);
547
439
  }
548
440
  };
549
- DashboardService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DashboardService, deps: [{ token: SisenseContextService }], target: i0.ɵɵFactoryTarget.Injectable });
550
- DashboardService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DashboardService, providedIn: 'root' });
551
- DashboardService = __decorate([
552
- TrackableService(['getDashboardModel', 'getDashboardModels'])
553
- ], DashboardService);
554
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DashboardService, decorators: [{
441
+ ThemeService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: ThemeService, deps: [{ token: SisenseContextService }, { token: THEME_CONFIG_TOKEN, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
442
+ ThemeService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: ThemeService, providedIn: 'root' });
443
+ ThemeService = __decorate([
444
+ TrackableService(['updateThemeSettings'])
445
+ ], ThemeService);
446
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: ThemeService, decorators: [{
555
447
  type: Injectable,
556
448
  args: [{
557
449
  providedIn: 'root',
558
450
  }]
559
- }], ctorParameters: function () { return [{ type: SisenseContextService }]; } });
451
+ }], ctorParameters: function () { return [{ type: SisenseContextService }, { type: undefined, decorators: [{
452
+ type: Optional
453
+ }, {
454
+ type: Inject,
455
+ args: [THEME_CONFIG_TOKEN]
456
+ }] }]; } });
560
457
 
561
458
  /**
562
- * Service for working with filter.
459
+ * An Angular component used for easily switching chart types or rendering multiple series of different chart types.
563
460
  *
564
- * @group Filters
461
+ * @example
462
+ * An example of using the `Chart` component to
463
+ * plot a column chart of the Sample Healthcare data source hosted in a Sisense instance:
464
+ *
465
+ * ```html
466
+ * <!--Component HTML template in .component.html-->
467
+ * <csdk-chart
468
+ * [chartType]="chart.chartType"
469
+ * [dataSet]="chart.dataSet"
470
+ * [dataOptions]="chart.dataOptions"
471
+ * [filters]="chart.filters"
472
+ * [styleOptions]="chart.styleOptions"
473
+ * />
474
+ * ```
475
+ *
476
+ * ```ts
477
+ * // Component behavior in .component.ts
478
+ * chart = {
479
+ * chartType: 'column' as ChartType,
480
+ * dataSet: DM.DataSource,
481
+ * dataOptions: {
482
+ * category: [DM.Admissions.Admission_Time.Months],
483
+ * value: [measureFactory.count(DM.Admissions.Patient_ID, 'Total Patients')],
484
+ * breakBy: [],
485
+ * },
486
+ * filters: [filterFactory.members(DM.Doctors.Specialty, ['Oncology', 'Cardiology'])],
487
+ * styleOptions: {
488
+ * width: 800,
489
+ * height: 500,
490
+ * xAxis: {
491
+ * title: {
492
+ * text: 'Months',
493
+ * enabled: true,
494
+ * },
495
+ * },
496
+ * yAxis: {
497
+ * title: {
498
+ * text: 'Total Patients',
499
+ * enabled: true,
500
+ * },
501
+ * },
502
+ * },
503
+ * };
504
+ * ```
505
+ *
506
+ * <img src="media://angular-chart-example.png" width="800px" />
507
+ * @shortDescription Common component for rendering charts of different types including table
508
+ * @group Charts
565
509
  */
566
- let FilterService = class FilterService {
567
- constructor(sisenseContextService) {
568
- this.sisenseContextService = sisenseContextService;
569
- }
510
+ class ChartComponent {
570
511
  /**
571
- * Retrieves members of the provided filter.
572
- *
573
- * Those members can be used to display a list of members in a third-party filter component such as Material UI Select.
574
- *
575
- * ## Example
576
- *
577
- * Retrieve selected members from a Filter on Country of the Sample ECommerce data model.
512
+ * Constructor for the `Chart` component.
578
513
  *
579
- * ```ts
580
- * try {
581
- * const data = await filterService.getFilterMembers({
582
- * filter: filterFactory.members(DM.Country.Country, ['United States', 'Canada'])
583
- * });
514
+ * @param sisenseContextService - Sisense context service
515
+ * @param themeService - Theme service
516
+ */
517
+ constructor(
518
+ /**
519
+ * Sisense context service
584
520
  *
585
- * const { selectedMembers, allMembers, excludeMembers, enableMultiSelection } = data;
586
- * console.log('selectedMembers', selectedMembers);
587
- * } catch (error) {
588
- * console.error('Error:', error);
589
- * }
590
- * ```
521
+ * @category Constructor
522
+ */
523
+ sisenseContextService,
524
+ /**
525
+ * Theme service
591
526
  *
592
- * @param params - Parameters for retrieving filter members
593
- * @returns Promise that resolves to the filter members data
527
+ * @category Constructor
594
528
  */
595
- async getFilterMembers(params) {
596
- const hookAdapter = new HookAdapter(useGetFilterMembers, [
529
+ themeService) {
530
+ this.sisenseContextService = sisenseContextService;
531
+ this.themeService = themeService;
532
+ /**
533
+ * {@inheritDoc @sisense/sdk-ui!ChartProps.onDataPointClick}
534
+ *
535
+ * @category Callbacks
536
+ */
537
+ this.dataPointClick = new EventEmitter();
538
+ /**
539
+ * {@inheritDoc @sisense/sdk-ui!ChartProps.onDataPointContextMenu}
540
+ *
541
+ * @category Callbacks
542
+ */
543
+ this.dataPointContextMenu = new EventEmitter();
544
+ /**
545
+ * {@inheritDoc @sisense/sdk-ui!ChartProps.onDataPointsSelected}
546
+ *
547
+ * @category Callbacks
548
+ */
549
+ this.dataPointsSelect = new EventEmitter();
550
+ this.componentAdapter = new ComponentAdapter(Chart, [
597
551
  createSisenseContextConnector(this.sisenseContextService),
552
+ createThemeContextConnector(this.themeService),
598
553
  ]);
599
- const resultPromise = new Promise((resolve, reject) => {
600
- hookAdapter.subscribe((res) => {
601
- const { isError, isSuccess, error } = res;
602
- if (isError) {
603
- reject(error);
604
- }
605
- else if (isSuccess) {
606
- resolve(res.data);
607
- }
608
- });
609
- });
610
- hookAdapter.run(params);
611
- return resultPromise.finally(() => {
612
- hookAdapter.destroy();
613
- });
614
- }
615
- };
616
- FilterService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: FilterService, deps: [{ token: SisenseContextService }], target: i0.ɵɵFactoryTarget.Injectable });
617
- FilterService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: FilterService, providedIn: 'root' });
618
- FilterService = __decorate([
619
- TrackableService(['getFilterMembers'])
620
- ], FilterService);
621
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: FilterService, decorators: [{
622
- type: Injectable,
623
- args: [{
624
- providedIn: 'root',
625
- }]
626
- }], ctorParameters: function () { return [{ type: SisenseContextService }]; } });
627
-
628
- /**
629
- * Service for working with Sisense Fusion hierarchies.
630
- *
631
- * @group Fusion Assets
632
- * @fusionEmbed
633
- */
634
- let HierarchyService = class HierarchyService {
635
- constructor(sisenseContextService) {
636
- this.sisenseContextService = sisenseContextService;
637
- }
638
- /**
639
- * Retrieves existing hierarchy models from the Sisense instance.
640
- *
641
- * @param params - Parameters to identify the target hierarchy models
642
- * @returns Hierarchy models array
643
- */
644
- async getHierarchyModels(params) {
645
- const app = await this.sisenseContextService.getApp();
646
- return getHierarchyModels(app.httpClient, params, app.defaultDataSource);
647
- }
648
- };
649
- HierarchyService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: HierarchyService, deps: [{ token: SisenseContextService }], target: i0.ɵɵFactoryTarget.Injectable });
650
- HierarchyService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: HierarchyService, providedIn: 'root' });
651
- HierarchyService = __decorate([
652
- TrackableService(['getHierarchyModels'])
653
- ], HierarchyService);
654
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: HierarchyService, decorators: [{
655
- type: Injectable,
656
- args: [{
657
- providedIn: 'root',
658
- }]
659
- }], ctorParameters: function () { return [{ type: SisenseContextService }]; } });
660
-
661
- /**
662
- * Service for executing data queries.
663
- *
664
- * @group Queries
665
- */
666
- let QueryService = class QueryService {
667
- constructor(sisenseContextService) {
668
- this.sisenseContextService = sisenseContextService;
669
- }
670
- /**
671
- * Executes a data query. If you want to display the query results, you can use
672
- * them to populate Compose SDK UI elements or third party UI elements.
673
- *
674
- * To learn how to populate third party UI elements with query results, see the
675
- * [External Charts Guide](/guides/sdk/guides/charts/guide-external-charts.html#query)
676
- *
677
- * @param params - Query parameters
678
- * @return Query result
679
- */
680
- async executeQuery(params) {
681
- const { dataSource, dimensions, measures, filters, highlights, count, offset, ungroup, beforeQuery, } = params;
682
- const app = await this.sisenseContextService.getApp();
683
- const { filters: filterList, relations: filterRelations } = getFilterListAndRelationsJaql(filters);
684
- const data = await executeQuery({
685
- dataSource,
686
- dimensions,
687
- measures,
688
- filters: filterList,
689
- filterRelations,
690
- highlights,
691
- count,
692
- offset,
693
- ungroup,
694
- }, app, { onBeforeQuery: beforeQuery });
695
- return { data };
696
554
  }
697
555
  /**
698
- * Executes a data query extracted from an existing widget in the Sisense instance.
699
- *
700
- * @param params - Parameters to identify the target widget
701
- * @returns Query result
556
+ * @internal
702
557
  */
703
- async executeQueryByWidgetId(params) {
704
- const app = await this.sisenseContextService.getApp();
705
- return executeQueryByWidgetId({
706
- ...params,
707
- app,
708
- onBeforeQuery: params.beforeQuery,
709
- });
558
+ ngAfterViewInit() {
559
+ this.componentAdapter.render(this.preactRef.nativeElement, this.getPreactComponentProps());
710
560
  }
711
561
  /**
712
- * Executes a data query for a pivot table.
713
- *
714
- * @param params - Pivot query parameters
715
- * @return Pivot query result
562
+ * @internal
716
563
  */
717
- async executePivotQuery(params) {
718
- const { dataSource, rows, columns, values, grandTotals, filters, highlights, count, offset, beforeQuery, } = params;
719
- const { filters: filterList, relations: filterRelations } = getFilterListAndRelationsJaql(filters);
720
- const app = await this.sisenseContextService.getApp();
721
- const data = await executePivotQuery({
722
- dataSource,
723
- rows,
724
- columns,
725
- values,
726
- grandTotals,
727
- filters: filterList,
728
- filterRelations,
729
- highlights,
730
- count,
731
- offset,
732
- }, app, { onBeforeQuery: beforeQuery });
733
- return { data };
564
+ ngOnChanges() {
565
+ if (this.preactRef) {
566
+ this.componentAdapter.render(this.preactRef.nativeElement, this.getPreactComponentProps());
567
+ }
734
568
  }
735
- /**
736
- * Executes a CSV data query.
737
- * Similar to {@link QueryService.executeQuery}, but returns the data in CSV format as text or as a stream.
738
- *
739
- * @param params - CSV query parameters
740
- * @return CSV query result
741
- */
742
- async executeCsvQuery(params) {
743
- const hookAdapter = new HookAdapter(useExecuteCsvQueryInternal, [
744
- createSisenseContextConnector(this.sisenseContextService),
745
- ]);
746
- const resultPromise = new Promise((resolve, reject) => {
747
- hookAdapter.subscribe((res) => {
748
- const { data, isSuccess, isError, error } = res;
749
- if (isSuccess) {
750
- resolve({ data });
751
- }
752
- else if (isError) {
753
- reject(error);
754
- }
755
- });
756
- });
757
- hookAdapter.run(params);
758
- return resultPromise.finally(() => {
759
- hookAdapter.destroy();
760
- });
569
+ getPreactComponentProps() {
570
+ return {
571
+ chartType: this.chartType,
572
+ dataSet: this.dataSet,
573
+ dataOptions: this.dataOptions,
574
+ filters: this.filters,
575
+ highlights: this.highlights,
576
+ styleOptions: this.styleOptions,
577
+ onBeforeRender: this.beforeRender?.bind(this),
578
+ onDataReady: this.dataReady?.bind(this),
579
+ onDataPointClick: (...[point, nativeEvent]) => this.dataPointClick.emit({ point, nativeEvent }),
580
+ onDataPointContextMenu: (...[point, nativeEvent]) => this.dataPointContextMenu.emit({ point, nativeEvent }),
581
+ onDataPointsSelected: (...[points, nativeEvent]) => this.dataPointsSelect.emit({ points, nativeEvent }),
582
+ };
761
583
  }
762
584
  /**
763
- * Executes a data query from custom widget component props.
764
- *
765
- * This method takes custom widget props (dataSource, dataOptions, filters, etc.)
766
- * and executes the appropriate data query
767
- *
768
- * @param params - Custom widget component props containing data source, data options, filters, etc.
769
- * @returns Promise resolving to query result with formatted data
585
+ * @internal
770
586
  */
771
- async executeCustomWidgetQuery(params) {
772
- const hookAdapter = new HookAdapter(useExecuteCustomWidgetQueryInternal, [
773
- createSisenseContextConnector(this.sisenseContextService),
774
- ]);
775
- const resultPromise = new Promise((resolve, reject) => {
776
- hookAdapter.subscribe((res) => {
777
- const { data, isSuccess, isError, error } = res;
778
- if (isSuccess) {
779
- resolve({ data });
780
- }
781
- else if (isError) {
782
- reject(error);
783
- }
784
- });
785
- });
786
- hookAdapter.run(params);
787
- return resultPromise.finally(() => {
788
- hookAdapter.destroy();
789
- });
587
+ ngOnDestroy() {
588
+ this.componentAdapter.destroy();
790
589
  }
791
- };
792
- QueryService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: QueryService, deps: [{ token: SisenseContextService }], target: i0.ɵɵFactoryTarget.Injectable });
793
- QueryServiceprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: QueryService, providedIn: 'root' });
794
- QueryService = __decorate([
795
- TrackableService([
796
- 'executeQuery',
797
- 'executeQueryByWidgetId',
798
- 'executePivotQuery',
799
- 'executeCustomWidgetQuery',
800
- ])
801
- ], QueryService);
802
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: QueryService, decorators: [{
803
- type: Injectable,
804
- args: [{
805
- providedIn: 'root',
806
- }]
807
- }], ctorParameters: function () { return [{ type: SisenseContextService }]; } });
590
+ }
591
+ ChartComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: ChartComponent, deps: [{ token: SisenseContextService }, { token: ThemeService }], target: i0.ɵɵFactoryTarget.Component });
592
+ ChartComponentcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: ChartComponent, selector: "csdk-chart", inputs: { chartType: "chartType", dataSet: "dataSet", dataOptions: "dataOptions", filters: "filters", highlights: "highlights", styleOptions: "styleOptions", beforeRender: "beforeRender", dataReady: "dataReady" }, outputs: { dataPointClick: "dataPointClick", dataPointContextMenu: "dataPointContextMenu", dataPointsSelect: "dataPointsSelect" }, viewQueries: [{ propertyName: "preactRef", first: true, predicate: ["preact"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "\n <div #preact class=\"csdk-full-size-container\"></div>\n", isInline: true, styles: [".csdk-full-size-container{width:100%;height:100%}\n"] });
593
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: ChartComponent, decorators: [{
594
+ type: Component,
595
+ args: [{ selector: 'csdk-chart', template: template, styles: [".csdk-full-size-container{width:100%;height:100%}\n"] }]
596
+ }], ctorParameters: function () { return [{ type: SisenseContextService }, { type: ThemeService }]; }, propDecorators: { preactRef: [{
597
+ type: ViewChild,
598
+ args: [rootId]
599
+ }], chartType: [{
600
+ type: Input
601
+ }], dataSet: [{
602
+ type: Input
603
+ }], dataOptions: [{
604
+ type: Input
605
+ }], filters: [{
606
+ type: Input
607
+ }], highlights: [{
608
+ type: Input
609
+ }], styleOptions: [{
610
+ type: Input
611
+ }], beforeRender: [{
612
+ type: Input
613
+ }], dataReady: [{
614
+ type: Input
615
+ }], dataPointClick: [{
616
+ type: Output
617
+ }], dataPointContextMenu: [{
618
+ type: Output
619
+ }], dataPointsSelect: [{
620
+ type: Output
621
+ }] } });
808
622
 
809
623
  /**
810
- * Service for working with Sisense Fusion widgets.
624
+ * A component similar to a {@link LineChartComponent},
625
+ * but with filled in areas under each line and an option to display them as stacked.
811
626
  *
812
- * @group Fusion Assets
813
- * @fusionEmbed
814
- */
815
- let WidgetService = class WidgetService {
816
- constructor(sisenseContextService) {
817
- this.sisenseContextService = sisenseContextService;
818
- }
819
- /**
820
- * Retrieves an existing widget model from the Sisense instance.
821
- *
822
- * @param params - Parameters to identify the target widget
823
- * @returns Widget model
824
- */
825
- async getWidgetModel(params) {
826
- const { dashboardOid, widgetOid } = params;
827
- const app = await this.sisenseContextService.getApp();
828
- return getWidgetModel(app.httpClient, dashboardOid, widgetOid);
829
- }
830
- };
831
- WidgetService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: WidgetService, deps: [{ token: SisenseContextService }], target: i0.ɵɵFactoryTarget.Injectable });
832
- WidgetService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: WidgetService, providedIn: 'root' });
833
- WidgetService = __decorate([
834
- TrackableService(['getWidgetModel'])
835
- ], WidgetService);
836
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: WidgetService, decorators: [{
837
- type: Injectable,
838
- args: [{
839
- providedIn: 'root',
840
- }]
841
- }], ctorParameters: function () { return [{ type: SisenseContextService }]; } });
627
+ * @example
628
+ * ```html
629
+ * <csdk-area-chart
630
+ * [dataSet]="chart.dataSet"
631
+ * [dataOptions]="chart.dataOptions"
632
+ * [highlights]="filters"
633
+ * [beforeRender]="onBeforeRender"
634
+ * (dataPointClick)="logArguments($event)"
635
+ * (dataPointContextMenu)="logArguments($event)"
636
+ * (dataPointsSelect)="logArguments($event)"
637
+ * />
638
+ * ```
639
+ * ```ts
640
+ import { Component } from '@angular/core';
641
+ import { measureFactory, filterFactory, Filter } from '@sisense/sdk-data';
642
+ import * as DM from '../../assets/sample-healthcare-model';
643
+ import type { ChartType } from '@sisense/sdk-ui-angular';
842
644
 
843
- class DecoratorsModule {
844
- constructor(sisenseContextService) {
845
- DecoratorsModule.sisenseContextService = sisenseContextService;
846
- }
847
- }
848
- DecoratorsModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DecoratorsModule, deps: [{ token: SisenseContextService }], target: i0.ɵɵFactoryTarget.NgModule });
849
- DecoratorsModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.10", ngImport: i0, type: DecoratorsModule });
850
- DecoratorsModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DecoratorsModule });
851
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DecoratorsModule, decorators: [{
852
- type: NgModule,
853
- args: [{
854
- declarations: [],
855
- exports: [],
856
- }]
857
- }], ctorParameters: function () { return [{ type: SisenseContextService }]; } });
645
+ @Component({
646
+ selector: 'app-analytics',
647
+ templateUrl: './analytics.component.html',
648
+ styleUrls: ['./analytics.component.scss'],
649
+ })
650
+ export class AnalyticsComponent {
651
+ DM = DM;
652
+ filters = [filterFactory.members(DM.Divisions.Divison_name, ['Cardiology', 'Neurology'])];
653
+ chart = {
654
+ chartType: 'column' as ChartType,
655
+ dataSet: DM.DataSource,
656
+ dataOptions: {
657
+ category: [DM.Divisions.Divison_name],
658
+ value: [measureFactory.sum(DM.Admissions.Cost_of_admission)],
659
+ breakBy: [],
660
+ },
661
+ };
858
662
 
859
- function Trackable(target, propertyKey, descriptor) {
860
- const originalMethod = descriptor.value;
861
- descriptor.value = function (...args) {
862
- track('sdkAngularServiceMethodExecuted', propertyKey);
863
- return originalMethod.apply(this, args);
864
- };
865
- return descriptor;
866
- }
867
- /** @internal */
868
- function TrackableService(trackableMethods) {
869
- return function (ServiceClass) {
870
- trackableMethods.forEach((methodName) => {
871
- // eslint-disable-next-line security/detect-object-injection
872
- const original = ServiceClass.prototype[methodName];
873
- // eslint-disable-next-line security/detect-object-injection
874
- ServiceClass.prototype[methodName] = function (...params) {
875
- track('sdkAngularServiceMethodExecuted', `${ServiceClass.name}.${methodName}`);
876
- return original.apply(this, params);
877
- };
878
- });
879
- };
663
+ onBeforeRender(options: any) {
664
+ console.log('beforeRender');
665
+ console.log(options);
666
+ return options;
667
+ }
668
+
669
+ logArguments(...args: any[]) {
670
+ console.log(args);
671
+ }
880
672
  }
881
- async function track(action, methodName) {
882
- try {
883
- const app = await DecoratorsModule.sisenseContextService.getApp();
884
- const trackingEnabled = app.settings?.trackingConfig?.enabled ?? true;
885
- if (app?.httpClient) {
886
- const payload = {
887
- packageName: 'sdk-ui-angular',
888
- packageVersion,
889
- methodName,
890
- };
891
- void trackProductEvent(action, payload, app.httpClient, !trackingEnabled);
892
- }
893
- }
894
- catch (e) {
895
- console.warn('tracking error', e);
673
+ * ```
674
+ * <img src="media://angular-area-chart-example.png" width="800px" />
675
+ * @group Charts
676
+ */
677
+ class AreaChartComponent {
678
+ constructor() {
679
+ /**
680
+ * {@inheritDoc @sisense/sdk-ui!AreaChartProps.onDataPointClick}
681
+ *
682
+ * @category Callbacks
683
+ */
684
+ this.dataPointClick = new EventEmitter();
685
+ /**
686
+ * {@inheritDoc @sisense/sdk-ui!AreaChartProps.onDataPointContextMenu}
687
+ *
688
+ * @category Callbacks
689
+ */
690
+ this.dataPointContextMenu = new EventEmitter();
691
+ /**
692
+ * {@inheritDoc @sisense/sdk-ui!AreaChartProps.onDataPointsSelected}
693
+ *
694
+ * @category Callbacks
695
+ */
696
+ this.dataPointsSelect = new EventEmitter();
697
+ /** @internal */
698
+ this.chartType = 'area';
896
699
  }
897
700
  }
701
+ AreaChartComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: AreaChartComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
702
+ AreaChartComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: AreaChartComponent, selector: "csdk-area-chart", inputs: { dataSet: "dataSet", dataOptions: "dataOptions", filters: "filters", highlights: "highlights", styleOptions: "styleOptions", beforeRender: "beforeRender", dataReady: "dataReady" }, outputs: { dataPointClick: "dataPointClick", dataPointContextMenu: "dataPointContextMenu", dataPointsSelect: "dataPointsSelect" }, ngImport: i0, template: `
703
+ <csdk-chart
704
+ [chartType]="chartType"
705
+ [dataSet]="dataSet"
706
+ [dataOptions]="dataOptions"
707
+ [filters]="filters"
708
+ [highlights]="highlights"
709
+ [styleOptions]="styleOptions"
710
+ [beforeRender]="beforeRender"
711
+ [dataReady]="dataReady"
712
+ (dataPointClick)="dataPointClick.emit($any($event))"
713
+ (dataPointContextMenu)="dataPointContextMenu.emit($any($event))"
714
+ (dataPointsSelect)="dataPointsSelect.emit($any($event))"
715
+ />
716
+ `, isInline: true, dependencies: [{ kind: "component", type: ChartComponent, selector: "csdk-chart", inputs: ["chartType", "dataSet", "dataOptions", "filters", "highlights", "styleOptions", "beforeRender", "dataReady"], outputs: ["dataPointClick", "dataPointContextMenu", "dataPointsSelect"] }] });
717
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: AreaChartComponent, decorators: [{
718
+ type: Component,
719
+ args: [{
720
+ selector: 'csdk-area-chart',
721
+ template: `
722
+ <csdk-chart
723
+ [chartType]="chartType"
724
+ [dataSet]="dataSet"
725
+ [dataOptions]="dataOptions"
726
+ [filters]="filters"
727
+ [highlights]="highlights"
728
+ [styleOptions]="styleOptions"
729
+ [beforeRender]="beforeRender"
730
+ [dataReady]="dataReady"
731
+ (dataPointClick)="dataPointClick.emit($any($event))"
732
+ (dataPointContextMenu)="dataPointContextMenu.emit($any($event))"
733
+ (dataPointsSelect)="dataPointsSelect.emit($any($event))"
734
+ />
735
+ `,
736
+ }]
737
+ }], propDecorators: { dataSet: [{
738
+ type: Input
739
+ }], dataOptions: [{
740
+ type: Input
741
+ }], filters: [{
742
+ type: Input
743
+ }], highlights: [{
744
+ type: Input
745
+ }], styleOptions: [{
746
+ type: Input
747
+ }], beforeRender: [{
748
+ type: Input
749
+ }], dataReady: [{
750
+ type: Input
751
+ }], dataPointClick: [{
752
+ type: Output
753
+ }], dataPointContextMenu: [{
754
+ type: Output
755
+ }], dataPointsSelect: [{
756
+ type: Output
757
+ }] } });
898
758
 
899
759
  /**
900
- * Token used to inject {@link ThemeConfig} into your application
760
+ * A component that displays a range of data over a given time period or across multiple categories.
761
+ * It is particularly useful for visualizing the minimum and maximum values in a dataset, along with
762
+ * the area between these values.
901
763
  *
902
764
  * @example
903
- *
904
- * Example of injecting both {@link SisenseContextConfig} and {@link ThemeConfig} into your application:
905
- *
906
- * ```ts
907
- * export const SISENSE_CONTEXT_CONFIG: SisenseContextConfig = {
908
- * url: "<instance url>", // replace with the URL of your Sisense instance
909
- * token: "<api token>", // replace with the API token of your user account
910
- * defaultDataSource: DM.DataSource,
911
- * };
912
- *
913
- * @NgModule({
914
- * imports: [
915
- * BrowserModule,
916
- * SdkUiModule,
917
- * ],
918
- * declarations: [AppComponent],
919
- * providers: [
920
- * { provide: SISENSE_CONTEXT_CONFIG_TOKEN, useValue: SISENSE_CONTEXT_CONFIG },
921
- * {
922
- * provide: THEME_CONFIG_TOKEN,
923
- * useValue: {
924
- * // initial theme settings
925
- * } as ThemeConfig,
926
- * },
927
- * ],
928
- * bootstrap: [AppComponent],
929
- * })
930
- * ```
931
- * @group Contexts
932
- */
933
- const THEME_CONFIG_TOKEN = new InjectionToken('theme configuration');
934
- /**
935
- * Service for working with Sisense Fusion themes.
936
- *
937
- * If no theme service is used, the current Fusion theme is applied by default.
938
- *
939
- * @group Contexts
940
- */
941
- let ThemeService = class ThemeService {
942
- constructor(sisenseContextService, themeConfig) {
943
- this.sisenseContextService = sisenseContextService;
944
- this.initializationPromise = Promise.resolve();
945
- this.themeSettings$ = new BehaviorSubject(getDefaultThemeSettings());
946
- this.initializationPromise = this.initThemeSettings(themeConfig?.theme);
947
- this.sisenseContextService
948
- .getApp$()
949
- // Skip current app value
950
- .pipe(skip(1))
951
- // Subscribe to new app values
952
- .subscribe({
953
- next: ({ app }) => {
954
- if (app) {
955
- this.initializationPromise = this.applyThemeSettings(app.settings.serverThemeSettings);
956
- }
957
- },
958
- });
959
- }
960
- async initThemeSettings(theme) {
961
- const app = await this.sisenseContextService.getApp();
962
- // apply system theme settings first
963
- await this.applyThemeSettings(app.settings.serverThemeSettings);
964
- if (theme) {
965
- // Manually tracks theme update during initialization as execution of updateThemeSettings for consistency.
966
- track('sdkAngularServiceMethodExecuted', 'ThemeService.updateThemeSettings');
967
- await this.applyThemeSettings(theme);
968
- }
969
- }
970
- async applyThemeSettings(theme) {
971
- try {
972
- const app = await this.sisenseContextService.getApp();
973
- const isThemeOid = typeof theme === 'string';
974
- let userThemeSettings = theme;
975
- if (isThemeOid) {
976
- userThemeSettings = await getThemeSettingsByOid(theme, app.httpClient);
977
- }
978
- const mergedThemeSettings = merge.withOptions({ mergeArrays: false }, this.themeSettings$.value, userThemeSettings);
979
- this.themeSettings$.next(mergedThemeSettings);
980
- }
981
- catch (error) {
982
- this.themeSettings$.error(error);
983
- }
984
- }
985
- /** @internal */
986
- getThemeSettings() {
987
- return this.themeSettings$.asObservable();
988
- }
989
- async updateThemeSettings(theme) {
990
- await this.initializationPromise;
991
- await this.applyThemeSettings(theme);
992
- }
993
- };
994
- ThemeService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: ThemeService, deps: [{ token: SisenseContextService }, { token: THEME_CONFIG_TOKEN, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
995
- ThemeService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: ThemeService, providedIn: 'root' });
996
- ThemeService = __decorate([
997
- TrackableService(['updateThemeSettings'])
998
- ], ThemeService);
999
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: ThemeService, decorators: [{
1000
- type: Injectable,
1001
- args: [{
1002
- providedIn: 'root',
1003
- }]
1004
- }], ctorParameters: function () { return [{ type: SisenseContextService }, { type: undefined, decorators: [{
1005
- type: Optional
1006
- }, {
1007
- type: Inject,
1008
- args: [THEME_CONFIG_TOKEN]
1009
- }] }]; } });
1010
-
1011
- /**
1012
- * An Angular component used for easily switching chart types or rendering multiple series of different chart types.
1013
- *
1014
- * @example
1015
- * An example of using the `Chart` component to
1016
- * plot a column chart of the Sample Healthcare data source hosted in a Sisense instance:
1017
- *
1018
- * ```html
1019
- * <!--Component HTML template in .component.html-->
1020
- * <csdk-chart
1021
- * [chartType]="chart.chartType"
1022
- * [dataSet]="chart.dataSet"
1023
- * [dataOptions]="chart.dataOptions"
1024
- * [filters]="chart.filters"
1025
- * [styleOptions]="chart.styleOptions"
1026
- * />
1027
- * ```
1028
- *
1029
- * ```ts
1030
- * // Component behavior in .component.ts
1031
- * chart = {
1032
- * chartType: 'column' as ChartType,
1033
- * dataSet: DM.DataSource,
1034
- * dataOptions: {
1035
- * category: [DM.Admissions.Admission_Time.Months],
1036
- * value: [measureFactory.count(DM.Admissions.Patient_ID, 'Total Patients')],
1037
- * breakBy: [],
1038
- * },
1039
- * filters: [filterFactory.members(DM.Doctors.Specialty, ['Oncology', 'Cardiology'])],
1040
- * styleOptions: {
1041
- * width: 800,
1042
- * height: 500,
1043
- * xAxis: {
1044
- * title: {
1045
- * text: 'Months',
1046
- * enabled: true,
1047
- * },
1048
- * },
1049
- * yAxis: {
1050
- * title: {
1051
- * text: 'Total Patients',
1052
- * enabled: true,
1053
- * },
1054
- * },
1055
- * },
1056
- * };
1057
- * ```
1058
- *
1059
- * <img src="media://angular-chart-example.png" width="800px" />
1060
- * @shortDescription Common component for rendering charts of different types including table
1061
- * @group Charts
1062
- */
1063
- class ChartComponent {
1064
- /**
1065
- * Constructor for the `Chart` component.
1066
- *
1067
- * @param sisenseContextService - Sisense context service
1068
- * @param themeService - Theme service
1069
- */
1070
- constructor(
1071
- /**
1072
- * Sisense context service
1073
- *
1074
- * @category Constructor
1075
- */
1076
- sisenseContextService,
1077
- /**
1078
- * Theme service
1079
- *
1080
- * @category Constructor
1081
- */
1082
- themeService) {
1083
- this.sisenseContextService = sisenseContextService;
1084
- this.themeService = themeService;
1085
- /**
1086
- * {@inheritDoc @sisense/sdk-ui!ChartProps.onDataPointClick}
1087
- *
1088
- * @category Callbacks
1089
- */
1090
- this.dataPointClick = new EventEmitter();
1091
- /**
1092
- * {@inheritDoc @sisense/sdk-ui!ChartProps.onDataPointContextMenu}
1093
- *
1094
- * @category Callbacks
1095
- */
1096
- this.dataPointContextMenu = new EventEmitter();
1097
- /**
1098
- * {@inheritDoc @sisense/sdk-ui!ChartProps.onDataPointsSelected}
1099
- *
1100
- * @category Callbacks
1101
- */
1102
- this.dataPointsSelect = new EventEmitter();
1103
- this.componentAdapter = new ComponentAdapter(Chart, [
1104
- createSisenseContextConnector(this.sisenseContextService),
1105
- createThemeContextConnector(this.themeService),
1106
- ]);
1107
- }
1108
- /**
1109
- * @internal
1110
- */
1111
- ngAfterViewInit() {
1112
- this.componentAdapter.render(this.preactRef.nativeElement, this.getPreactComponentProps());
1113
- }
1114
- /**
1115
- * @internal
1116
- */
1117
- ngOnChanges() {
1118
- if (this.preactRef) {
1119
- this.componentAdapter.render(this.preactRef.nativeElement, this.getPreactComponentProps());
1120
- }
1121
- }
1122
- getPreactComponentProps() {
1123
- return {
1124
- chartType: this.chartType,
1125
- dataSet: this.dataSet,
1126
- dataOptions: this.dataOptions,
1127
- filters: this.filters,
1128
- highlights: this.highlights,
1129
- styleOptions: this.styleOptions,
1130
- onBeforeRender: this.beforeRender?.bind(this),
1131
- onDataReady: this.dataReady?.bind(this),
1132
- onDataPointClick: (...[point, nativeEvent]) => this.dataPointClick.emit({ point, nativeEvent }),
1133
- onDataPointContextMenu: (...[point, nativeEvent]) => this.dataPointContextMenu.emit({ point, nativeEvent }),
1134
- onDataPointsSelected: (...[points, nativeEvent]) => this.dataPointsSelect.emit({ points, nativeEvent }),
1135
- };
1136
- }
1137
- /**
1138
- * @internal
1139
- */
1140
- ngOnDestroy() {
1141
- this.componentAdapter.destroy();
1142
- }
1143
- }
1144
- ChartComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: ChartComponent, deps: [{ token: SisenseContextService }, { token: ThemeService }], target: i0.ɵɵFactoryTarget.Component });
1145
- ChartComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: ChartComponent, selector: "csdk-chart", inputs: { chartType: "chartType", dataSet: "dataSet", dataOptions: "dataOptions", filters: "filters", highlights: "highlights", styleOptions: "styleOptions", beforeRender: "beforeRender", dataReady: "dataReady" }, outputs: { dataPointClick: "dataPointClick", dataPointContextMenu: "dataPointContextMenu", dataPointsSelect: "dataPointsSelect" }, viewQueries: [{ propertyName: "preactRef", first: true, predicate: ["preact"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "\n <div #preact class=\"csdk-full-size-container\"></div>\n", isInline: true, styles: [".csdk-full-size-container{width:100%;height:100%}\n"] });
1146
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: ChartComponent, decorators: [{
1147
- type: Component,
1148
- args: [{ selector: 'csdk-chart', template: template, styles: [".csdk-full-size-container{width:100%;height:100%}\n"] }]
1149
- }], ctorParameters: function () { return [{ type: SisenseContextService }, { type: ThemeService }]; }, propDecorators: { preactRef: [{
1150
- type: ViewChild,
1151
- args: [rootId]
1152
- }], chartType: [{
1153
- type: Input
1154
- }], dataSet: [{
1155
- type: Input
1156
- }], dataOptions: [{
1157
- type: Input
1158
- }], filters: [{
1159
- type: Input
1160
- }], highlights: [{
1161
- type: Input
1162
- }], styleOptions: [{
1163
- type: Input
1164
- }], beforeRender: [{
1165
- type: Input
1166
- }], dataReady: [{
1167
- type: Input
1168
- }], dataPointClick: [{
1169
- type: Output
1170
- }], dataPointContextMenu: [{
1171
- type: Output
1172
- }], dataPointsSelect: [{
1173
- type: Output
1174
- }] } });
1175
-
1176
- /**
1177
- * A component similar to a {@link LineChartComponent},
1178
- * but with filled in areas under each line and an option to display them as stacked.
1179
- *
1180
- * @example
1181
- * ```html
1182
- * <csdk-area-chart
1183
- * [dataSet]="chart.dataSet"
1184
- * [dataOptions]="chart.dataOptions"
1185
- * [highlights]="filters"
1186
- * [beforeRender]="onBeforeRender"
1187
- * (dataPointClick)="logArguments($event)"
1188
- * (dataPointContextMenu)="logArguments($event)"
1189
- * (dataPointsSelect)="logArguments($event)"
1190
- * />
765
+ * ```html
766
+ * <csdk-area-range-chart
767
+ * [dataSet]="chart.dataSet"
768
+ * [dataOptions]="chart.dataOptions"
769
+ * [highlights]="filters"
770
+ * [beforeRender]="onBeforeRender"
771
+ * (dataPointClick)="logArguments($event)"
772
+ * (dataPointContextMenu)="logArguments($event)"
773
+ * (dataPointsSelect)="logArguments($event)"
774
+ * />
1191
775
  * ```
1192
776
  * ```ts
1193
777
  import { Component } from '@angular/core';
1194
778
  import { measureFactory, filterFactory, Filter } from '@sisense/sdk-data';
1195
779
  import * as DM from '../../assets/sample-healthcare-model';
1196
- import type { ChartType } from '@sisense/sdk-ui-angular';
780
+ import type { ChartType, RangeChartDataOptions } from '@sisense/sdk-ui-angular';
1197
781
 
1198
782
  @Component({
1199
783
  selector: 'app-analytics',
@@ -1204,162 +788,25 @@ export class AnalyticsComponent {
1204
788
  DM = DM;
1205
789
  filters = [filterFactory.members(DM.Divisions.Divison_name, ['Cardiology', 'Neurology'])];
1206
790
  chart = {
1207
- chartType: 'column' as ChartType,
791
+ chartType: 'arearange' as ChartType,
1208
792
  dataSet: DM.DataSource,
1209
793
  dataOptions: {
1210
- category: [DM.Divisions.Divison_name],
1211
- value: [measureFactory.sum(DM.Admissions.Cost_of_admission)],
794
+ category: [DM.Admissions.Admission_Time.Years],
795
+ value: [
796
+ {
797
+ title: 'Admission Cost Range',
798
+ upperBound: measureFactory.multiply(
799
+ measureFactory.sum(DM.Admissions.Cost_of_admission, 'Lower Admission'),
800
+ 0.6,
801
+ ),
802
+ lowerBound: measureFactory.multiply(
803
+ measureFactory.sum(DM.Admissions.Cost_of_admission, 'Upper Admission'),
804
+ 1.4,
805
+ ),
806
+ }
807
+ ],
1212
808
  breakBy: [],
1213
- },
1214
- };
1215
-
1216
- onBeforeRender(options: any) {
1217
- console.log('beforeRender');
1218
- console.log(options);
1219
- return options;
1220
- }
1221
-
1222
- logArguments(...args: any[]) {
1223
- console.log(args);
1224
- }
1225
- }
1226
- * ```
1227
- * <img src="media://angular-area-chart-example.png" width="800px" />
1228
- * @group Charts
1229
- */
1230
- class AreaChartComponent {
1231
- constructor() {
1232
- /**
1233
- * {@inheritDoc @sisense/sdk-ui!AreaChartProps.onDataPointClick}
1234
- *
1235
- * @category Callbacks
1236
- */
1237
- this.dataPointClick = new EventEmitter();
1238
- /**
1239
- * {@inheritDoc @sisense/sdk-ui!AreaChartProps.onDataPointContextMenu}
1240
- *
1241
- * @category Callbacks
1242
- */
1243
- this.dataPointContextMenu = new EventEmitter();
1244
- /**
1245
- * {@inheritDoc @sisense/sdk-ui!AreaChartProps.onDataPointsSelected}
1246
- *
1247
- * @category Callbacks
1248
- */
1249
- this.dataPointsSelect = new EventEmitter();
1250
- /** @internal */
1251
- this.chartType = 'area';
1252
- }
1253
- }
1254
- AreaChartComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: AreaChartComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1255
- AreaChartComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: AreaChartComponent, selector: "csdk-area-chart", inputs: { dataSet: "dataSet", dataOptions: "dataOptions", filters: "filters", highlights: "highlights", styleOptions: "styleOptions", beforeRender: "beforeRender", dataReady: "dataReady" }, outputs: { dataPointClick: "dataPointClick", dataPointContextMenu: "dataPointContextMenu", dataPointsSelect: "dataPointsSelect" }, ngImport: i0, template: `
1256
- <csdk-chart
1257
- [chartType]="chartType"
1258
- [dataSet]="dataSet"
1259
- [dataOptions]="dataOptions"
1260
- [filters]="filters"
1261
- [highlights]="highlights"
1262
- [styleOptions]="styleOptions"
1263
- [beforeRender]="beforeRender"
1264
- [dataReady]="dataReady"
1265
- (dataPointClick)="dataPointClick.emit($any($event))"
1266
- (dataPointContextMenu)="dataPointContextMenu.emit($any($event))"
1267
- (dataPointsSelect)="dataPointsSelect.emit($any($event))"
1268
- />
1269
- `, isInline: true, dependencies: [{ kind: "component", type: ChartComponent, selector: "csdk-chart", inputs: ["chartType", "dataSet", "dataOptions", "filters", "highlights", "styleOptions", "beforeRender", "dataReady"], outputs: ["dataPointClick", "dataPointContextMenu", "dataPointsSelect"] }] });
1270
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: AreaChartComponent, decorators: [{
1271
- type: Component,
1272
- args: [{
1273
- selector: 'csdk-area-chart',
1274
- template: `
1275
- <csdk-chart
1276
- [chartType]="chartType"
1277
- [dataSet]="dataSet"
1278
- [dataOptions]="dataOptions"
1279
- [filters]="filters"
1280
- [highlights]="highlights"
1281
- [styleOptions]="styleOptions"
1282
- [beforeRender]="beforeRender"
1283
- [dataReady]="dataReady"
1284
- (dataPointClick)="dataPointClick.emit($any($event))"
1285
- (dataPointContextMenu)="dataPointContextMenu.emit($any($event))"
1286
- (dataPointsSelect)="dataPointsSelect.emit($any($event))"
1287
- />
1288
- `,
1289
- }]
1290
- }], propDecorators: { dataSet: [{
1291
- type: Input
1292
- }], dataOptions: [{
1293
- type: Input
1294
- }], filters: [{
1295
- type: Input
1296
- }], highlights: [{
1297
- type: Input
1298
- }], styleOptions: [{
1299
- type: Input
1300
- }], beforeRender: [{
1301
- type: Input
1302
- }], dataReady: [{
1303
- type: Input
1304
- }], dataPointClick: [{
1305
- type: Output
1306
- }], dataPointContextMenu: [{
1307
- type: Output
1308
- }], dataPointsSelect: [{
1309
- type: Output
1310
- }] } });
1311
-
1312
- /**
1313
- * A component that displays a range of data over a given time period or across multiple categories.
1314
- * It is particularly useful for visualizing the minimum and maximum values in a dataset, along with
1315
- * the area between these values.
1316
- *
1317
- * @example
1318
- * ```html
1319
- * <csdk-area-range-chart
1320
- * [dataSet]="chart.dataSet"
1321
- * [dataOptions]="chart.dataOptions"
1322
- * [highlights]="filters"
1323
- * [beforeRender]="onBeforeRender"
1324
- * (dataPointClick)="logArguments($event)"
1325
- * (dataPointContextMenu)="logArguments($event)"
1326
- * (dataPointsSelect)="logArguments($event)"
1327
- * />
1328
- * ```
1329
- * ```ts
1330
- import { Component } from '@angular/core';
1331
- import { measureFactory, filterFactory, Filter } from '@sisense/sdk-data';
1332
- import * as DM from '../../assets/sample-healthcare-model';
1333
- import type { ChartType, RangeChartDataOptions } from '@sisense/sdk-ui-angular';
1334
-
1335
- @Component({
1336
- selector: 'app-analytics',
1337
- templateUrl: './analytics.component.html',
1338
- styleUrls: ['./analytics.component.scss'],
1339
- })
1340
- export class AnalyticsComponent {
1341
- DM = DM;
1342
- filters = [filterFactory.members(DM.Divisions.Divison_name, ['Cardiology', 'Neurology'])];
1343
- chart = {
1344
- chartType: 'arearange' as ChartType,
1345
- dataSet: DM.DataSource,
1346
- dataOptions: {
1347
- category: [DM.Admissions.Admission_Time.Years],
1348
- value: [
1349
- {
1350
- title: 'Admission Cost Range',
1351
- upperBound: measureFactory.multiply(
1352
- measureFactory.sum(DM.Admissions.Cost_of_admission, 'Lower Admission'),
1353
- 0.6,
1354
- ),
1355
- lowerBound: measureFactory.multiply(
1356
- measureFactory.sum(DM.Admissions.Cost_of_admission, 'Upper Admission'),
1357
- 1.4,
1358
- ),
1359
- }
1360
- ],
1361
- breakBy: [],
1362
- } as RangeChartDataOptions,
809
+ } as RangeChartDataOptions,
1363
810
  };
1364
811
 
1365
812
  onBeforeRender(options: any) {
@@ -2471,140 +1918,844 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
2471
1918
  }] } });
2472
1919
 
2473
1920
  /**
2474
- * A component representing data in a circular graph with the data shown as slices of a whole,
2475
- * with each slice representing a proportion of the total.
1921
+ * A component representing data in a circular graph with the data shown as slices of a whole,
1922
+ * with each slice representing a proportion of the total.
1923
+ *
1924
+ * @example
1925
+ * ```html
1926
+ * <csdk-pie-chart
1927
+ * [dataSet]="chart.dataSet"
1928
+ * [dataOptions]="chart.dataOptions"
1929
+ * [highlights]="filters"
1930
+ * [beforeRender]="onBeforeRender"
1931
+ * (dataPointClick)="logArguments($event)"
1932
+ * (dataPointContextMenu)="logArguments($event)"
1933
+ * (dataPointsSelect)="logArguments($event)"
1934
+ * />
1935
+ * ```
1936
+ * ```ts
1937
+ import { Component } from '@angular/core';
1938
+ import { measureFactory, filterFactory } from '@sisense/sdk-data';
1939
+ import * as DM from '../../assets/sample-healthcare-model';
1940
+ import type { ChartType } from '@sisense/sdk-ui-angular';
1941
+
1942
+ @Component({
1943
+ selector: 'app-analytics',
1944
+ templateUrl: './analytics.component.html',
1945
+ styleUrls: ['./analytics.component.scss'],
1946
+ })
1947
+ export class AnalyticsComponent {
1948
+ DM = DM;
1949
+ filters = [filterFactory.members(DM.Divisions.Divison_name, ['Cardiology', 'Neurology'])];
1950
+ chart = {
1951
+ chartType: 'column' as ChartType,
1952
+ dataSet: DM.DataSource,
1953
+ dataOptions: {
1954
+ category: [DM.Divisions.Divison_name],
1955
+ value: [measureFactory.sum(DM.Admissions.Cost_of_admission)],
1956
+ breakBy: [],
1957
+ },
1958
+ };
1959
+
1960
+ onBeforeRender(options: any) {
1961
+ console.log('beforeRender');
1962
+ console.log(options);
1963
+ return options;
1964
+ }
1965
+
1966
+ logArguments(...args: any[]) {
1967
+ console.log(args);
1968
+ }
1969
+ }
1970
+ * ```
1971
+ * <img src="media://angular-pie-chart-example.png" width="800px" />
1972
+ * @group Charts
1973
+ */
1974
+ class PieChartComponent {
1975
+ constructor() {
1976
+ /**
1977
+ * {@inheritDoc @sisense/sdk-ui!PieChartProps.onDataPointClick}
1978
+ *
1979
+ * @category Callbacks
1980
+ */
1981
+ this.dataPointClick = new EventEmitter();
1982
+ /**
1983
+ * {@inheritDoc @sisense/sdk-ui!PieChartProps.onDataPointContextMenu}
1984
+ *
1985
+ * @category Callbacks
1986
+ */
1987
+ this.dataPointContextMenu = new EventEmitter();
1988
+ /**
1989
+ * {@inheritDoc @sisense/sdk-ui!PieChartProps.onDataPointsSelected}
1990
+ *
1991
+ * @category Callbacks
1992
+ */
1993
+ this.dataPointsSelect = new EventEmitter();
1994
+ /** @internal */
1995
+ this.chartType = 'pie';
1996
+ }
1997
+ }
1998
+ PieChartComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: PieChartComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1999
+ PieChartComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: PieChartComponent, selector: "csdk-pie-chart", inputs: { dataSet: "dataSet", dataOptions: "dataOptions", filters: "filters", highlights: "highlights", styleOptions: "styleOptions", beforeRender: "beforeRender", dataReady: "dataReady" }, outputs: { dataPointClick: "dataPointClick", dataPointContextMenu: "dataPointContextMenu", dataPointsSelect: "dataPointsSelect" }, ngImport: i0, template: `
2000
+ <csdk-chart
2001
+ [chartType]="chartType"
2002
+ [dataSet]="dataSet"
2003
+ [dataOptions]="dataOptions"
2004
+ [filters]="filters"
2005
+ [highlights]="highlights"
2006
+ [styleOptions]="styleOptions"
2007
+ [beforeRender]="beforeRender"
2008
+ [dataReady]="dataReady"
2009
+ (dataPointClick)="dataPointClick.emit($any($event))"
2010
+ (dataPointContextMenu)="dataPointContextMenu.emit($any($event))"
2011
+ (dataPointsSelect)="dataPointsSelect.emit($any($event))"
2012
+ />
2013
+ `, isInline: true, dependencies: [{ kind: "component", type: ChartComponent, selector: "csdk-chart", inputs: ["chartType", "dataSet", "dataOptions", "filters", "highlights", "styleOptions", "beforeRender", "dataReady"], outputs: ["dataPointClick", "dataPointContextMenu", "dataPointsSelect"] }] });
2014
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: PieChartComponent, decorators: [{
2015
+ type: Component,
2016
+ args: [{
2017
+ selector: 'csdk-pie-chart',
2018
+ template: `
2019
+ <csdk-chart
2020
+ [chartType]="chartType"
2021
+ [dataSet]="dataSet"
2022
+ [dataOptions]="dataOptions"
2023
+ [filters]="filters"
2024
+ [highlights]="highlights"
2025
+ [styleOptions]="styleOptions"
2026
+ [beforeRender]="beforeRender"
2027
+ [dataReady]="dataReady"
2028
+ (dataPointClick)="dataPointClick.emit($any($event))"
2029
+ (dataPointContextMenu)="dataPointContextMenu.emit($any($event))"
2030
+ (dataPointsSelect)="dataPointsSelect.emit($any($event))"
2031
+ />
2032
+ `,
2033
+ }]
2034
+ }], propDecorators: { dataSet: [{
2035
+ type: Input
2036
+ }], dataOptions: [{
2037
+ type: Input
2038
+ }], filters: [{
2039
+ type: Input
2040
+ }], highlights: [{
2041
+ type: Input
2042
+ }], styleOptions: [{
2043
+ type: Input
2044
+ }], beforeRender: [{
2045
+ type: Input
2046
+ }], dataReady: [{
2047
+ type: Input
2048
+ }], dataPointClick: [{
2049
+ type: Output
2050
+ }], dataPointContextMenu: [{
2051
+ type: Output
2052
+ }], dataPointsSelect: [{
2053
+ type: Output
2054
+ }] } });
2055
+
2056
+ /**
2057
+ * Service for rendering components dynamically.
2058
+ *
2059
+ * @internal
2060
+ */
2061
+ class DynamicRenderer {
2062
+ constructor(appRef, injector, envInjector) {
2063
+ this.appRef = appRef;
2064
+ this.injector = injector;
2065
+ this.envInjector = envInjector;
2066
+ }
2067
+ renderComponent(component, props) {
2068
+ const componentRef = createComponent(component, {
2069
+ environmentInjector: this.envInjector,
2070
+ elementInjector: this.injector,
2071
+ });
2072
+ // Apply props to the component instance
2073
+ Object.assign(componentRef.instance, props);
2074
+ // Attach the component to the application
2075
+ this.appRef.attachView(componentRef.hostView);
2076
+ // Get the DOM element
2077
+ const domElem = componentRef.hostView.rootNodes[0];
2078
+ // Create destroy function
2079
+ const destroy = () => {
2080
+ // Detach from application
2081
+ this.appRef.detachView(componentRef.hostView);
2082
+ // Destroy the component
2083
+ componentRef.destroy();
2084
+ };
2085
+ return {
2086
+ element: domElem,
2087
+ componentRef,
2088
+ destroy,
2089
+ };
2090
+ }
2091
+ }
2092
+ DynamicRenderer.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DynamicRenderer, deps: [{ token: i0.ApplicationRef }, { token: i0.Injector }, { token: i0.EnvironmentInjector }], target: i0.ɵɵFactoryTarget.Injectable });
2093
+ DynamicRenderer.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DynamicRenderer, providedIn: 'root' });
2094
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DynamicRenderer, decorators: [{
2095
+ type: Injectable,
2096
+ args: [{ providedIn: 'root' }]
2097
+ }], ctorParameters: function () { return [{ type: i0.ApplicationRef }, { type: i0.Injector }, { type: i0.EnvironmentInjector }]; } });
2098
+
2099
+ /**
2100
+ * Service for working with custom widgets.
2101
+ *
2102
+ * @group Dashboards
2103
+ */
2104
+ class CustomWidgetsService {
2105
+ constructor(
2106
+ /** @internal */
2107
+ dynamicRenderer) {
2108
+ this.dynamicRenderer = dynamicRenderer;
2109
+ this.customWidgetsMap$ = new BehaviorSubject(new Map([['tabber-buttons', TabberButtonsWidget]]));
2110
+ }
2111
+ /**
2112
+ * Registers a new custom widget.
2113
+ *
2114
+ * @param customWidgetType - The unique identifier for the custom widget type.
2115
+ * @param customWidget - The custom widget component class to register.
2116
+ */
2117
+ registerCustomWidget(customWidgetType, customWidget) {
2118
+ const customWidgetPreactComponent = (props) => {
2119
+ const renderedComponent = this.dynamicRenderer.renderComponent(customWidget, props);
2120
+ return createWrapperElement(renderedComponent.element, () => renderedComponent.destroy());
2121
+ };
2122
+ const customWidgetsMap = this.customWidgetsMap$.value;
2123
+ if (!customWidgetsMap.has(customWidgetType)) {
2124
+ customWidgetsMap.set(customWidgetType, customWidgetPreactComponent);
2125
+ this.customWidgetsMap$.next(customWidgetsMap);
2126
+ }
2127
+ }
2128
+ /**
2129
+ * Checks if a custom widget is registered.
2130
+ *
2131
+ * @param customWidgetType - The type of the custom widget.
2132
+ * @returns True if the custom widget is registered, false otherwise.
2133
+ */
2134
+ hasCustomWidget(customWidgetType) {
2135
+ return this.customWidgetsMap$.value.has(customWidgetType);
2136
+ }
2137
+ }
2138
+ CustomWidgetsService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: CustomWidgetsService, deps: [{ token: DynamicRenderer }], target: i0.ɵɵFactoryTarget.Injectable });
2139
+ CustomWidgetsService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: CustomWidgetsService, providedIn: 'root' });
2140
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: CustomWidgetsService, decorators: [{
2141
+ type: Injectable,
2142
+ args: [{
2143
+ providedIn: 'root',
2144
+ }]
2145
+ }], ctorParameters: function () { return [{ type: DynamicRenderer }]; } });
2146
+
2147
+ function translateToPreactWidgetProps(widgetProps) {
2148
+ const { beforeRender, dataReady, beforeMenuOpen, dataPointClick, dataPointContextMenu, dataPointsSelect, ...commonWidgetProps } = widgetProps;
2149
+ return {
2150
+ ...commonWidgetProps,
2151
+ onBeforeRender: beforeRender,
2152
+ onDataReady: dataReady,
2153
+ onBeforeMenuOpen: beforeMenuOpen,
2154
+ onDataPointClick: dataPointClick
2155
+ ? (...[point, nativeEvent]) => dataPointClick({
2156
+ point,
2157
+ nativeEvent,
2158
+ })
2159
+ : undefined,
2160
+ onDataPointContextMenu: dataPointContextMenu
2161
+ ? (...[point, nativeEvent]) => dataPointContextMenu({
2162
+ point,
2163
+ nativeEvent,
2164
+ })
2165
+ : undefined,
2166
+ onDataPointsSelected: dataPointsSelect
2167
+ ? (...[points, nativeEvent]) => dataPointsSelect({ points, nativeEvent })
2168
+ : undefined,
2169
+ };
2170
+ }
2171
+ function translateFromPreactWidgetProps(widgetProps) {
2172
+ const { onBeforeRender, onDataReady, onBeforeMenuOpen, onDataPointClick, onDataPointContextMenu, onDataPointsSelected, ...commonWidgetProps } = widgetProps;
2173
+ return {
2174
+ ...commonWidgetProps,
2175
+ beforeRender: onBeforeRender,
2176
+ dataReady: onDataReady,
2177
+ beforeMenuOpen: onBeforeMenuOpen,
2178
+ dataPointClick: onDataPointClick
2179
+ ? ({ point, nativeEvent }) => onDataPointClick(point, nativeEvent)
2180
+ : undefined,
2181
+ dataPointContextMenu: onDataPointContextMenu
2182
+ ? ({ point, nativeEvent }) => onDataPointContextMenu(point, nativeEvent)
2183
+ : undefined,
2184
+ dataPointsSelect: onDataPointsSelected
2185
+ ? ({ points, nativeEvent }) => onDataPointsSelected(points, nativeEvent)
2186
+ : undefined,
2187
+ };
2188
+ }
2189
+
2190
+ function translateToPreactDashboardProps(dashboardProps) {
2191
+ return {
2192
+ ...dashboardProps,
2193
+ widgets: dashboardProps.widgets.map(translateToPreactWidgetProps),
2194
+ };
2195
+ }
2196
+ function translateFromPreactDashboardProps(dashboardProps) {
2197
+ return {
2198
+ ...dashboardProps,
2199
+ widgets: dashboardProps.widgets.map(translateFromPreactWidgetProps),
2200
+ };
2201
+ }
2202
+
2203
+ /**
2204
+ * Service for working with Sisense Fusion dashboards.
2205
+ *
2206
+ * **Note:** Dashboard and Widget extensions based on JS scripts and add-ons in Fusion – for example, Blox and Jump To Dashboard – are not supported.
2207
+ *
2208
+ * @group Fusion Assets
2209
+ * @fusionEmbed
2210
+ */
2211
+ let DashboardService = class DashboardService {
2212
+ constructor(sisenseContextService) {
2213
+ this.sisenseContextService = sisenseContextService;
2214
+ }
2215
+ /**
2216
+ * Retrieves an existing dashboard model from the Sisense instance.
2217
+ *
2218
+ * @param dashboardOid - Identifier of the dashboard
2219
+ * @param options - Advanced configuration options
2220
+ * @returns Dashboard model
2221
+ */
2222
+ async getDashboardModel(dashboardOid, options) {
2223
+ const app = await this.sisenseContextService.getApp();
2224
+ return getDashboardModel(app.httpClient, dashboardOid, options);
2225
+ }
2226
+ /**
2227
+ * Retrieves existing dashboard models from the Sisense instance.
2228
+ *
2229
+ * @param options - Advanced configuration options
2230
+ * @returns Dashboard models array
2231
+ */
2232
+ async getDashboardModels(options) {
2233
+ const app = await this.sisenseContextService.getApp();
2234
+ return getDashboardModels(app.httpClient, options);
2235
+ }
2236
+ /**
2237
+ * Сomposes dashboard or separate dashboard elements into a coordinated dashboard
2238
+ * with cross filtering, and change detection.
2239
+ *
2240
+ * @example
2241
+ * An example of using the `createComposedDashboard` to construct a composed dashboard and render it:
2242
+ * ```html
2243
+ <!--Component HTML template in example.component.html-->
2244
+ <div *ngIf="dashboard$ | async as dashboard">
2245
+ <csdk-filter-tile
2246
+ *ngFor="let filter of getDashboardFilters(dashboard); trackBy: trackByIndex"
2247
+ [filter]="filter"
2248
+ />
2249
+ <csdk-widget
2250
+ *ngFor="let widget of dashboard.widgets; trackBy: trackByIndex"
2251
+ [id]="widget.id"
2252
+ [widgetType]="widget.widgetType"
2253
+ [chartType]="widget.chartType"
2254
+ [customWidgetType]="widget.customWidgetType"
2255
+ [dataSource]="widget.dataSource"
2256
+ [dataOptions]="widget.dataOptions"
2257
+ [filters]="widget.filters"
2258
+ [highlights]="widget.highlights"
2259
+ [styleOptions]="widget.styleOptions"
2260
+ [drilldownOptions]="widget.drilldownOptions"
2261
+ [title]="widget.title"
2262
+ [description]="widget.description"
2263
+ [beforeMenuOpen]="widget.beforeMenuOpen"
2264
+ (dataPointClick)="widget.dataPointClick?.($event)"
2265
+ (dataPointContextMenu)="widget.dataPointContextMenu?.($event)"
2266
+ (dataPointsSelect)="widget.dataPointsSelect?.($event)"
2267
+ />
2268
+ </div>
2269
+ * ```
2270
+ *
2271
+ * ```ts
2272
+ // Component behavior in example.component.ts
2273
+ import { Component, OnDestroy } from '@angular/core';
2274
+ import { BehaviorSubject } from 'rxjs';
2275
+ import { DashboardService, type DashboardProps } from '@sisense/sdk-ui-angular';
2276
+
2277
+ @Component({
2278
+ selector: 'example',
2279
+ templateUrl: './example.component.html',
2280
+ styleUrls: ['./example.component.scss'],
2281
+ })
2282
+ export class ExampleComponent implements OnDestroy {
2283
+ dashboard$: BehaviorSubject<DashboardProps> | undefined;
2284
+ private composedDashboard: ReturnType<DashboardService['createComposedDashboard']> | undefined;
2285
+
2286
+ constructor(private dashboardService: DashboardService) {}
2287
+
2288
+ ngOnInit() {
2289
+ const initialDashboard: DashboardProps = { ... };
2290
+ this.composedDashboard = this.dashboardService.createComposedDashboard(initialDashboard);
2291
+ this.dashboard$ = this.composedDashboard.dashboard$;
2292
+ }
2293
+
2294
+ ngOnDestroy() {
2295
+ this.composedDashboard?.destroy();
2296
+ }
2297
+
2298
+ trackByIndex = (index: number) => index;
2299
+
2300
+ getDashboardFilters = ({ filters }: DashboardProps) => Array.isArray(filters) ? filters : [];
2301
+ }
2302
+ * ```
2303
+ * @param initialDashboard - Initial dashboard
2304
+ * @param options - Configuration options
2305
+ * @returns Reactive composed dashboard object and API methods for interacting with it.
2306
+ * The returned object includes a `destroy()` method that should be called when
2307
+ * the dashboard is no longer needed to prevent memory leaks (e.g., in `ngOnDestroy`).
2308
+ */
2309
+ createComposedDashboard(initialDashboard, options = {}) {
2310
+ const hookAdapter = new HookAdapter((useComposedDashboardInternal), [createSisenseContextConnector(this.sisenseContextService)]);
2311
+ const dashboard$ = new BehaviorSubject(initialDashboard);
2312
+ hookAdapter.subscribe(({ dashboard }) => {
2313
+ dashboard$.next(translateFromPreactDashboardProps(dashboard));
2314
+ });
2315
+ hookAdapter.run(translateToPreactDashboardProps(initialDashboard), options);
2316
+ const setFilters = createHookApiFacade(hookAdapter, 'setFilters', true);
2317
+ const setWidgetsLayout = createHookApiFacade(hookAdapter, 'setWidgetsLayout', true);
2318
+ const destroy = () => {
2319
+ hookAdapter.destroy();
2320
+ dashboard$.complete();
2321
+ };
2322
+ return {
2323
+ dashboard$,
2324
+ setFilters,
2325
+ setWidgetsLayout,
2326
+ destroy,
2327
+ };
2328
+ }
2329
+ };
2330
+ DashboardService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DashboardService, deps: [{ token: SisenseContextService }], target: i0.ɵɵFactoryTarget.Injectable });
2331
+ DashboardService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DashboardService, providedIn: 'root' });
2332
+ DashboardService = __decorate([
2333
+ TrackableService(['getDashboardModel', 'getDashboardModels'])
2334
+ ], DashboardService);
2335
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DashboardService, decorators: [{
2336
+ type: Injectable,
2337
+ args: [{
2338
+ providedIn: 'root',
2339
+ }]
2340
+ }], ctorParameters: function () { return [{ type: SisenseContextService }]; } });
2341
+
2342
+ /**
2343
+ * Service for working with filter.
2344
+ *
2345
+ * @group Filters
2346
+ */
2347
+ let FilterService = class FilterService {
2348
+ constructor(sisenseContextService) {
2349
+ this.sisenseContextService = sisenseContextService;
2350
+ }
2351
+ /**
2352
+ * Retrieves members of the provided filter.
2353
+ *
2354
+ * Those members can be used to display a list of members in a third-party filter component such as Material UI Select.
2355
+ *
2356
+ * ## Example
2357
+ *
2358
+ * Retrieve selected members from a Filter on Country of the Sample ECommerce data model.
2359
+ *
2360
+ * ```ts
2361
+ * try {
2362
+ * const data = await filterService.getFilterMembers({
2363
+ * filter: filterFactory.members(DM.Country.Country, ['United States', 'Canada'])
2364
+ * });
2365
+ *
2366
+ * const { selectedMembers, allMembers, excludeMembers, enableMultiSelection } = data;
2367
+ * console.log('selectedMembers', selectedMembers);
2368
+ * } catch (error) {
2369
+ * console.error('Error:', error);
2370
+ * }
2371
+ * ```
2372
+ *
2373
+ * @param params - Parameters for retrieving filter members
2374
+ * @returns Promise that resolves to the filter members data
2375
+ */
2376
+ async getFilterMembers(params) {
2377
+ const hookAdapter = new HookAdapter(useGetFilterMembers, [
2378
+ createSisenseContextConnector(this.sisenseContextService),
2379
+ ]);
2380
+ const resultPromise = new Promise((resolve, reject) => {
2381
+ hookAdapter.subscribe((res) => {
2382
+ const { isError, isSuccess, error } = res;
2383
+ if (isError) {
2384
+ reject(error);
2385
+ }
2386
+ else if (isSuccess) {
2387
+ resolve(res.data);
2388
+ }
2389
+ });
2390
+ });
2391
+ hookAdapter.run(params);
2392
+ return resultPromise.finally(() => {
2393
+ hookAdapter.destroy();
2394
+ });
2395
+ }
2396
+ };
2397
+ FilterService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: FilterService, deps: [{ token: SisenseContextService }], target: i0.ɵɵFactoryTarget.Injectable });
2398
+ FilterService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: FilterService, providedIn: 'root' });
2399
+ FilterService = __decorate([
2400
+ TrackableService(['getFilterMembers'])
2401
+ ], FilterService);
2402
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: FilterService, decorators: [{
2403
+ type: Injectable,
2404
+ args: [{
2405
+ providedIn: 'root',
2406
+ }]
2407
+ }], ctorParameters: function () { return [{ type: SisenseContextService }]; } });
2408
+
2409
+ /**
2410
+ * Service for working with Sisense Fusion hierarchies.
2411
+ *
2412
+ * @group Fusion Assets
2413
+ * @fusionEmbed
2414
+ */
2415
+ let HierarchyService = class HierarchyService {
2416
+ constructor(sisenseContextService) {
2417
+ this.sisenseContextService = sisenseContextService;
2418
+ }
2419
+ /**
2420
+ * Retrieves existing hierarchy models from the Sisense instance.
2421
+ *
2422
+ * @param params - Parameters to identify the target hierarchy models
2423
+ * @returns Hierarchy models array
2424
+ */
2425
+ async getHierarchyModels(params) {
2426
+ const app = await this.sisenseContextService.getApp();
2427
+ return getHierarchyModels(app.httpClient, params, app.defaultDataSource);
2428
+ }
2429
+ };
2430
+ HierarchyService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: HierarchyService, deps: [{ token: SisenseContextService }], target: i0.ɵɵFactoryTarget.Injectable });
2431
+ HierarchyService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: HierarchyService, providedIn: 'root' });
2432
+ HierarchyService = __decorate([
2433
+ TrackableService(['getHierarchyModels'])
2434
+ ], HierarchyService);
2435
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: HierarchyService, decorators: [{
2436
+ type: Injectable,
2437
+ args: [{
2438
+ providedIn: 'root',
2439
+ }]
2440
+ }], ctorParameters: function () { return [{ type: SisenseContextService }]; } });
2441
+
2442
+ /**
2443
+ * Service for executing data queries.
2444
+ *
2445
+ * @group Queries
2446
+ */
2447
+ let QueryService = class QueryService {
2448
+ constructor(sisenseContextService) {
2449
+ this.sisenseContextService = sisenseContextService;
2450
+ }
2451
+ /**
2452
+ * Executes a data query. If you want to display the query results, you can use
2453
+ * them to populate Compose SDK UI elements or third party UI elements.
2454
+ *
2455
+ * To learn how to populate third party UI elements with query results, see the
2456
+ * [External Charts Guide](/guides/sdk/guides/charts/guide-external-charts.html#query)
2457
+ *
2458
+ * @param params - Query parameters
2459
+ * @return Query result
2460
+ */
2461
+ async executeQuery(params) {
2462
+ const { dataSource, dimensions, measures, filters, highlights, count, offset, ungroup, beforeQuery, } = params;
2463
+ const app = await this.sisenseContextService.getApp();
2464
+ const { filters: filterList, relations: filterRelations } = getFilterListAndRelationsJaql(filters);
2465
+ const data = await executeQuery({
2466
+ dataSource,
2467
+ dimensions,
2468
+ measures,
2469
+ filters: filterList,
2470
+ filterRelations,
2471
+ highlights,
2472
+ count,
2473
+ offset,
2474
+ ungroup,
2475
+ }, app, { onBeforeQuery: beforeQuery });
2476
+ return { data };
2477
+ }
2478
+ /**
2479
+ * Executes a data query extracted from an existing widget in the Sisense instance.
2480
+ *
2481
+ * @param params - Parameters to identify the target widget
2482
+ * @returns Query result
2483
+ */
2484
+ async executeQueryByWidgetId(params) {
2485
+ const app = await this.sisenseContextService.getApp();
2486
+ return executeQueryByWidgetId({
2487
+ ...params,
2488
+ app,
2489
+ onBeforeQuery: params.beforeQuery,
2490
+ });
2491
+ }
2492
+ /**
2493
+ * Executes a data query for a pivot table.
2494
+ *
2495
+ * @param params - Pivot query parameters
2496
+ * @return Pivot query result
2497
+ */
2498
+ async executePivotQuery(params) {
2499
+ const { dataSource, rows, columns, values, grandTotals, filters, highlights, count, offset, beforeQuery, } = params;
2500
+ const { filters: filterList, relations: filterRelations } = getFilterListAndRelationsJaql(filters);
2501
+ const app = await this.sisenseContextService.getApp();
2502
+ const data = await executePivotQuery({
2503
+ dataSource,
2504
+ rows,
2505
+ columns,
2506
+ values,
2507
+ grandTotals,
2508
+ filters: filterList,
2509
+ filterRelations,
2510
+ highlights,
2511
+ count,
2512
+ offset,
2513
+ }, app, { onBeforeQuery: beforeQuery });
2514
+ return { data };
2515
+ }
2516
+ /**
2517
+ * Executes a CSV data query.
2518
+ * Similar to {@link QueryService.executeQuery}, but returns the data in CSV format as text or as a stream.
2519
+ *
2520
+ * @param params - CSV query parameters
2521
+ * @return CSV query result
2522
+ */
2523
+ async executeCsvQuery(params) {
2524
+ const hookAdapter = new HookAdapter(useExecuteCsvQueryInternal, [
2525
+ createSisenseContextConnector(this.sisenseContextService),
2526
+ ]);
2527
+ const resultPromise = new Promise((resolve, reject) => {
2528
+ hookAdapter.subscribe((res) => {
2529
+ const { data, isSuccess, isError, error } = res;
2530
+ if (isSuccess) {
2531
+ resolve({ data });
2532
+ }
2533
+ else if (isError) {
2534
+ reject(error);
2535
+ }
2536
+ });
2537
+ });
2538
+ hookAdapter.run(params);
2539
+ return resultPromise.finally(() => {
2540
+ hookAdapter.destroy();
2541
+ });
2542
+ }
2543
+ /**
2544
+ * Executes a data query from custom widget component props.
2545
+ *
2546
+ * This method takes custom widget props (dataSource, dataOptions, filters, etc.)
2547
+ * and executes the appropriate data query
2548
+ *
2549
+ * @param params - Custom widget component props containing data source, data options, filters, etc.
2550
+ * @returns Promise resolving to query result with formatted data
2551
+ */
2552
+ async executeCustomWidgetQuery(params) {
2553
+ const hookAdapter = new HookAdapter(useExecuteCustomWidgetQueryInternal, [
2554
+ createSisenseContextConnector(this.sisenseContextService),
2555
+ ]);
2556
+ const resultPromise = new Promise((resolve, reject) => {
2557
+ hookAdapter.subscribe((res) => {
2558
+ const { data, isSuccess, isError, error } = res;
2559
+ if (isSuccess) {
2560
+ resolve({ data });
2561
+ }
2562
+ else if (isError) {
2563
+ reject(error);
2564
+ }
2565
+ });
2566
+ });
2567
+ hookAdapter.run(params);
2568
+ return resultPromise.finally(() => {
2569
+ hookAdapter.destroy();
2570
+ });
2571
+ }
2572
+ };
2573
+ QueryService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: QueryService, deps: [{ token: SisenseContextService }], target: i0.ɵɵFactoryTarget.Injectable });
2574
+ QueryService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: QueryService, providedIn: 'root' });
2575
+ QueryService = __decorate([
2576
+ TrackableService([
2577
+ 'executeQuery',
2578
+ 'executeQueryByWidgetId',
2579
+ 'executePivotQuery',
2580
+ 'executeCustomWidgetQuery',
2581
+ ])
2582
+ ], QueryService);
2583
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: QueryService, decorators: [{
2584
+ type: Injectable,
2585
+ args: [{
2586
+ providedIn: 'root',
2587
+ }]
2588
+ }], ctorParameters: function () { return [{ type: SisenseContextService }]; } });
2589
+
2590
+ /**
2591
+ * Service for working with Sisense Fusion widgets.
2476
2592
  *
2477
- * @example
2478
- * ```html
2479
- * <csdk-pie-chart
2480
- * [dataSet]="chart.dataSet"
2481
- * [dataOptions]="chart.dataOptions"
2482
- * [highlights]="filters"
2483
- * [beforeRender]="onBeforeRender"
2484
- * (dataPointClick)="logArguments($event)"
2485
- * (dataPointContextMenu)="logArguments($event)"
2486
- * (dataPointsSelect)="logArguments($event)"
2487
- * />
2488
- * ```
2489
- * ```ts
2490
- import { Component } from '@angular/core';
2491
- import { measureFactory, filterFactory } from '@sisense/sdk-data';
2492
- import * as DM from '../../assets/sample-healthcare-model';
2493
- import type { ChartType } from '@sisense/sdk-ui-angular';
2494
-
2495
- @Component({
2496
- selector: 'app-analytics',
2497
- templateUrl: './analytics.component.html',
2498
- styleUrls: ['./analytics.component.scss'],
2499
- })
2500
- export class AnalyticsComponent {
2501
- DM = DM;
2502
- filters = [filterFactory.members(DM.Divisions.Divison_name, ['Cardiology', 'Neurology'])];
2503
- chart = {
2504
- chartType: 'column' as ChartType,
2505
- dataSet: DM.DataSource,
2506
- dataOptions: {
2507
- category: [DM.Divisions.Divison_name],
2508
- value: [measureFactory.sum(DM.Admissions.Cost_of_admission)],
2509
- breakBy: [],
2510
- },
2511
- };
2512
-
2513
- onBeforeRender(options: any) {
2514
- console.log('beforeRender');
2515
- console.log(options);
2516
- return options;
2517
- }
2518
-
2519
- logArguments(...args: any[]) {
2520
- console.log(args);
2521
- }
2522
- }
2523
- * ```
2524
- * <img src="media://angular-pie-chart-example.png" width="800px" />
2525
- * @group Charts
2593
+ * @group Fusion Assets
2594
+ * @fusionEmbed
2526
2595
  */
2527
- class PieChartComponent {
2528
- constructor() {
2529
- /**
2530
- * {@inheritDoc @sisense/sdk-ui!PieChartProps.onDataPointClick}
2531
- *
2532
- * @category Callbacks
2533
- */
2534
- this.dataPointClick = new EventEmitter();
2535
- /**
2536
- * {@inheritDoc @sisense/sdk-ui!PieChartProps.onDataPointContextMenu}
2537
- *
2538
- * @category Callbacks
2539
- */
2540
- this.dataPointContextMenu = new EventEmitter();
2541
- /**
2542
- * {@inheritDoc @sisense/sdk-ui!PieChartProps.onDataPointsSelected}
2543
- *
2544
- * @category Callbacks
2545
- */
2546
- this.dataPointsSelect = new EventEmitter();
2547
- /** @internal */
2548
- this.chartType = 'pie';
2596
+ let WidgetService = class WidgetService {
2597
+ constructor(sisenseContextService, themeService) {
2598
+ this.sisenseContextService = sisenseContextService;
2599
+ this.themeService = themeService;
2549
2600
  }
2550
- }
2551
- PieChartComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: PieChartComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2552
- PieChartComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: PieChartComponent, selector: "csdk-pie-chart", inputs: { dataSet: "dataSet", dataOptions: "dataOptions", filters: "filters", highlights: "highlights", styleOptions: "styleOptions", beforeRender: "beforeRender", dataReady: "dataReady" }, outputs: { dataPointClick: "dataPointClick", dataPointContextMenu: "dataPointContextMenu", dataPointsSelect: "dataPointsSelect" }, ngImport: i0, template: `
2553
- <csdk-chart
2554
- [chartType]="chartType"
2555
- [dataSet]="dataSet"
2556
- [dataOptions]="dataOptions"
2557
- [filters]="filters"
2558
- [highlights]="highlights"
2559
- [styleOptions]="styleOptions"
2560
- [beforeRender]="beforeRender"
2561
- [dataReady]="dataReady"
2562
- (dataPointClick)="dataPointClick.emit($any($event))"
2563
- (dataPointContextMenu)="dataPointContextMenu.emit($any($event))"
2564
- (dataPointsSelect)="dataPointsSelect.emit($any($event))"
2565
- />
2566
- `, isInline: true, dependencies: [{ kind: "component", type: ChartComponent, selector: "csdk-chart", inputs: ["chartType", "dataSet", "dataOptions", "filters", "highlights", "styleOptions", "beforeRender", "dataReady"], outputs: ["dataPointClick", "dataPointContextMenu", "dataPointsSelect"] }] });
2567
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: PieChartComponent, decorators: [{
2568
- type: Component,
2601
+ /**
2602
+ * Retrieves an existing widget model from the Sisense instance.
2603
+ *
2604
+ * @param params - Parameters to identify the target widget
2605
+ * @returns Widget model
2606
+ */
2607
+ async getWidgetModel(params) {
2608
+ const { dashboardOid, widgetOid } = params;
2609
+ const app = await this.sisenseContextService.getApp();
2610
+ return getWidgetModel(app.httpClient, dashboardOid, widgetOid);
2611
+ }
2612
+ /**
2613
+ * Adds Jump To Dashboard (JTD) functionality to widget props.
2614
+ *
2615
+ * Jump To Dashboard (JTD) allows users to navigate from one dashboard to another when interacting with widgets,
2616
+ * such as clicking on chart data points or using context menus. This method is particularly useful when rendering
2617
+ * Widget components directly (not through a Dashboard component), but you still want JTD navigation functionality.
2618
+ *
2619
+ * For widgets that are part of a dashboard, consider using `applyJtdConfig` or `applyJtdConfigs` instead,
2620
+ * as they apply JTD configuration at the dashboard level rather than individual widget level.
2621
+ *
2622
+ * Note: dashboard-only 'includeDashboardFilters' is not supported and would just be ignored, since we do not have a dashboard in the current context.
2623
+ *
2624
+ * This method enhances the provided widget props with JTD navigation capabilities, including:
2625
+ * - Click and right-click event handlers for navigation
2626
+ * - Hyperlink styling for actionable pivot cells (when applicable)
2627
+ * - JTD icon display in widget headers
2628
+ * @example
2629
+ * ```TypeScript
2630
+ * import { Component, OnDestroy } from '@angular/core';
2631
+ * import {
2632
+ * WidgetService,
2633
+ * widgetModelTranslator,
2634
+ * type WidgetProps,
2635
+ * } from '@sisense/sdk-ui-angular';
2636
+ * import { BehaviorSubject } from 'rxjs';
2637
+ *
2638
+ * @Component({
2639
+ * selector: 'code-example',
2640
+ * template: `
2641
+ * <csdk-widget
2642
+ * *ngIf="widgetProps$ && (widgetProps$ | async) as widgetProps"
2643
+ * [id]="widgetProps.id"
2644
+ * [widgetType]="widgetProps.widgetType"
2645
+ * [chartType]="widgetProps.chartType"
2646
+ * [title]="widgetProps.title"
2647
+ * [dataSource]="widgetProps.dataSource"
2648
+ * [dataOptions]="widgetProps.dataOptions"
2649
+ * [filters]="widgetProps.filters"
2650
+ * [highlights]="widgetProps.highlights"
2651
+ * [styleOptions]="widgetProps.styleOptions"
2652
+ * [beforeMenuOpen]="widgetProps.beforeMenuOpen"
2653
+ * (dataPointClick)="widgetProps.dataPointClick?.($event)"
2654
+ * (dataPointContextMenu)="widgetProps.dataPointContextMenu?.($event)"
2655
+ * (dataPointsSelect)="widgetProps.dataPointsSelect?.($event)"
2656
+ * />
2657
+ * `,
2658
+ * })
2659
+ * export class CodeExample implements OnDestroy {
2660
+ * constructor(private widgetService: WidgetService) {}
2661
+ *
2662
+ * widgetProps$: BehaviorSubject<WidgetProps | null> | null = null;
2663
+ * private jtdDestroy: (() => void) | null = null;
2664
+ *
2665
+ * async ngOnInit(): Promise<void> {
2666
+ * const widget = await this.widgetService.getWidgetModel({
2667
+ * dashboardOid: '65a82171719e7f004018691c',
2668
+ * widgetOid: '65a82171719e7f004018691f',
2669
+ * });
2670
+ *
2671
+ * const baseProps = widget
2672
+ * ? widgetModelTranslator.toWidgetProps(widget)
2673
+ * : null;
2674
+ *
2675
+ * if (baseProps) {
2676
+ * const jtdConfig = {
2677
+ * targets: [{ id: 'target-dashboard-id', caption: 'Details' }],
2678
+ * interaction: { triggerMethod: 'rightclick' },
2679
+ * };
2680
+ * const jtdResult = this.widgetService.createJtdWidget(
2681
+ * baseProps,
2682
+ * jtdConfig,
2683
+ * );
2684
+ * this.widgetProps$ = jtdResult.widget$;
2685
+ * this.jtdDestroy = jtdResult.destroy;
2686
+ * }
2687
+ * }
2688
+ *
2689
+ * ngOnDestroy(): void {
2690
+ * this.jtdDestroy?.();
2691
+ * }
2692
+ * }
2693
+ * ```
2694
+ *
2695
+ * @param widgetProps - Base widget props to enhance with JTD functionality
2696
+ * @param jtdConfig - JTD configuration defining navigation targets and behavior
2697
+ * @returns Object containing:
2698
+ * - `widget$`: The observable that emits enhanced widget props with JTD handlers.
2699
+ * - `destroy`: Function to clean up resources. Call this when the component is destroyed.
2700
+ * @group Dashboards
2701
+ */
2702
+ createJtdWidget(widgetProps, jtdConfig) {
2703
+ // Create BehaviorSubject initialized with base props (or null)
2704
+ const enhancedProps$ = new BehaviorSubject(widgetProps);
2705
+ if (!widgetProps) {
2706
+ return {
2707
+ widget$: enhancedProps$,
2708
+ destroy: () => {
2709
+ enhancedProps$.complete();
2710
+ },
2711
+ };
2712
+ }
2713
+ // Create HookAdapter with useJtdWidget hook and context connectors
2714
+ const hookAdapter = new HookAdapter(useJtdWidget, [
2715
+ createSisenseContextConnector(this.sisenseContextService),
2716
+ createThemeContextConnector(this.themeService),
2717
+ ]);
2718
+ // Convert Angular props to preact props
2719
+ const preactProps = translateToPreactWidgetProps(widgetProps);
2720
+ // Subscribe to hook adapter results and capture the subscription
2721
+ const hookAdapterSubscription = hookAdapter.subscribe((enhancedPreactProps) => {
2722
+ if (enhancedPreactProps) {
2723
+ // Convert back to Angular props
2724
+ const angularProps = translateFromPreactWidgetProps(enhancedPreactProps);
2725
+ enhancedProps$.next(angularProps);
2726
+ }
2727
+ else {
2728
+ enhancedProps$.next(null);
2729
+ }
2730
+ });
2731
+ // Run the hook with widget props and JTD config
2732
+ // This will trigger the subscription above asynchronously when React contexts are ready
2733
+ hookAdapter.run(preactProps, jtdConfig);
2734
+ // Return the BehaviorSubject and destroy function for cleanup
2735
+ return {
2736
+ widget$: enhancedProps$,
2737
+ destroy: () => {
2738
+ // Unsubscribe from hook adapter
2739
+ hookAdapterSubscription.unsubscribe();
2740
+ // Destroy the hook adapter to clean up React components and contexts
2741
+ hookAdapter.destroy();
2742
+ // Complete the BehaviorSubject to release subscribers and avoid leaks
2743
+ enhancedProps$.complete();
2744
+ },
2745
+ };
2746
+ }
2747
+ };
2748
+ WidgetService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: WidgetService, deps: [{ token: SisenseContextService }, { token: ThemeService }], target: i0.ɵɵFactoryTarget.Injectable });
2749
+ WidgetService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: WidgetService, providedIn: 'root' });
2750
+ WidgetService = __decorate([
2751
+ TrackableService(['getWidgetModel', 'createJtdWidget'])
2752
+ ], WidgetService);
2753
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: WidgetService, decorators: [{
2754
+ type: Injectable,
2569
2755
  args: [{
2570
- selector: 'csdk-pie-chart',
2571
- template: `
2572
- <csdk-chart
2573
- [chartType]="chartType"
2574
- [dataSet]="dataSet"
2575
- [dataOptions]="dataOptions"
2576
- [filters]="filters"
2577
- [highlights]="highlights"
2578
- [styleOptions]="styleOptions"
2579
- [beforeRender]="beforeRender"
2580
- [dataReady]="dataReady"
2581
- (dataPointClick)="dataPointClick.emit($any($event))"
2582
- (dataPointContextMenu)="dataPointContextMenu.emit($any($event))"
2583
- (dataPointsSelect)="dataPointsSelect.emit($any($event))"
2584
- />
2585
- `,
2756
+ providedIn: 'root',
2586
2757
  }]
2587
- }], propDecorators: { dataSet: [{
2588
- type: Input
2589
- }], dataOptions: [{
2590
- type: Input
2591
- }], filters: [{
2592
- type: Input
2593
- }], highlights: [{
2594
- type: Input
2595
- }], styleOptions: [{
2596
- type: Input
2597
- }], beforeRender: [{
2598
- type: Input
2599
- }], dataReady: [{
2600
- type: Input
2601
- }], dataPointClick: [{
2602
- type: Output
2603
- }], dataPointContextMenu: [{
2604
- type: Output
2605
- }], dataPointsSelect: [{
2606
- type: Output
2607
- }] } });
2758
+ }], ctorParameters: function () { return [{ type: SisenseContextService }, { type: ThemeService }]; } });
2608
2759
 
2609
2760
  /**
2610
2761
  * Pivot Table with and pagination.
@@ -2671,6 +2822,18 @@ class PivotTableComponent {
2671
2822
  constructor(sisenseContextService, themeService) {
2672
2823
  this.sisenseContextService = sisenseContextService;
2673
2824
  this.themeService = themeService;
2825
+ /**
2826
+ * {@inheritDoc @sisense/sdk-ui!PivotTableProps.onDataPointClick}
2827
+ *
2828
+ * @category Callbacks
2829
+ */
2830
+ this.dataPointClick = new EventEmitter();
2831
+ /**
2832
+ * {@inheritDoc @sisense/sdk-ui!PivotTableProps.onDataPointContextMenu}
2833
+ *
2834
+ * @category Callbacks
2835
+ */
2836
+ this.dataPointContextMenu = new EventEmitter();
2674
2837
  this.componentAdapter = new ComponentAdapter(PivotTable, [
2675
2838
  createSisenseContextConnector(this.sisenseContextService),
2676
2839
  createThemeContextConnector(this.themeService),
@@ -2693,6 +2856,8 @@ class PivotTableComponent {
2693
2856
  filters: this.filters,
2694
2857
  highlights: this.highlights,
2695
2858
  styleOptions: this.styleOptions,
2859
+ onDataPointClick: (...[point, nativeEvent]) => this.dataPointClick.emit({ point, nativeEvent }),
2860
+ onDataPointContextMenu: (...[point, nativeEvent]) => this.dataPointContextMenu.emit({ point, nativeEvent }),
2696
2861
  };
2697
2862
  }
2698
2863
  /** @internal */
@@ -2701,7 +2866,7 @@ class PivotTableComponent {
2701
2866
  }
2702
2867
  }
2703
2868
  PivotTableComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: PivotTableComponent, deps: [{ token: SisenseContextService }, { token: ThemeService }], target: i0.ɵɵFactoryTarget.Component });
2704
- PivotTableComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: PivotTableComponent, selector: "csdk-pivot-table", inputs: { dataSet: "dataSet", dataOptions: "dataOptions", filters: "filters", highlights: "highlights", styleOptions: "styleOptions" }, viewQueries: [{ propertyName: "preactRef", first: true, predicate: ["preact"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "\n <div #preact class=\"csdk-full-size-container\"></div>\n", isInline: true, styles: [".csdk-full-size-container{width:100%;height:100%}\n"] });
2869
+ PivotTableComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: PivotTableComponent, selector: "csdk-pivot-table", inputs: { dataSet: "dataSet", dataOptions: "dataOptions", filters: "filters", highlights: "highlights", styleOptions: "styleOptions" }, outputs: { dataPointClick: "dataPointClick", dataPointContextMenu: "dataPointContextMenu" }, viewQueries: [{ propertyName: "preactRef", first: true, predicate: ["preact"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "\n <div #preact class=\"csdk-full-size-container\"></div>\n", isInline: true, styles: [".csdk-full-size-container{width:100%;height:100%}\n"] });
2705
2870
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: PivotTableComponent, decorators: [{
2706
2871
  type: Component,
2707
2872
  args: [{ selector: 'csdk-pivot-table', template: template, styles: [".csdk-full-size-container{width:100%;height:100%}\n"] }]
@@ -2718,6 +2883,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
2718
2883
  type: Input
2719
2884
  }], styleOptions: [{
2720
2885
  type: Input
2886
+ }], dataPointClick: [{
2887
+ type: Output
2888
+ }], dataPointContextMenu: [{
2889
+ type: Output
2721
2890
  }] } });
2722
2891
 
2723
2892
  /**
@@ -5186,6 +5355,18 @@ class PivotTableWidgetComponent {
5186
5355
  constructor(sisenseContextService, themeService) {
5187
5356
  this.sisenseContextService = sisenseContextService;
5188
5357
  this.themeService = themeService;
5358
+ /**
5359
+ * {@inheritDoc @sisense/sdk-ui!PivotTableWidgetProps.onDataPointClick}
5360
+ *
5361
+ * @category Callbacks
5362
+ */
5363
+ this.dataPointClick = new EventEmitter();
5364
+ /**
5365
+ * {@inheritDoc @sisense/sdk-ui!PivotTableWidgetProps.onDataPointContextMenu}
5366
+ *
5367
+ * @category Callbacks
5368
+ */
5369
+ this.dataPointContextMenu = new EventEmitter();
5189
5370
  this.componentAdapter = new ComponentAdapter(PivotTableWidget, [
5190
5371
  createSisenseContextConnector(this.sisenseContextService),
5191
5372
  createThemeContextConnector(this.themeService),
@@ -5208,8 +5389,11 @@ class PivotTableWidgetComponent {
5208
5389
  filters: this.filters,
5209
5390
  highlights: this.highlights,
5210
5391
  styleOptions: this.styleOptions,
5392
+ drilldownOptions: this.drilldownOptions,
5211
5393
  title: this.title,
5212
5394
  description: this.description,
5395
+ onDataPointClick: (...[point, nativeEvent]) => this.dataPointClick.emit({ point, nativeEvent }),
5396
+ onDataPointContextMenu: (...[point, nativeEvent]) => this.dataPointContextMenu.emit({ point, nativeEvent }),
5213
5397
  };
5214
5398
  }
5215
5399
  /** @internal */
@@ -5218,7 +5402,7 @@ class PivotTableWidgetComponent {
5218
5402
  }
5219
5403
  }
5220
5404
  PivotTableWidgetComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: PivotTableWidgetComponent, deps: [{ token: SisenseContextService }, { token: ThemeService }], target: i0.ɵɵFactoryTarget.Component });
5221
- PivotTableWidgetComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: PivotTableWidgetComponent, selector: "csdk-pivot-table-widget", inputs: { dataSource: "dataSource", dataOptions: "dataOptions", filters: "filters", highlights: "highlights", styleOptions: "styleOptions", title: "title", description: "description" }, viewQueries: [{ propertyName: "preactRef", first: true, predicate: ["preact"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "\n <div #preact class=\"csdk-full-size-container\"></div>\n", isInline: true, styles: [".csdk-full-size-container{width:100%;height:100%}\n"] });
5405
+ PivotTableWidgetComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: PivotTableWidgetComponent, selector: "csdk-pivot-table-widget", inputs: { dataSource: "dataSource", dataOptions: "dataOptions", filters: "filters", highlights: "highlights", styleOptions: "styleOptions", drilldownOptions: "drilldownOptions", title: "title", description: "description" }, outputs: { dataPointClick: "dataPointClick", dataPointContextMenu: "dataPointContextMenu" }, viewQueries: [{ propertyName: "preactRef", first: true, predicate: ["preact"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "\n <div #preact class=\"csdk-full-size-container\"></div>\n", isInline: true, styles: [".csdk-full-size-container{width:100%;height:100%}\n"] });
5222
5406
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: PivotTableWidgetComponent, decorators: [{
5223
5407
  type: Component,
5224
5408
  args: [{ selector: 'csdk-pivot-table-widget', template: template, styles: [".csdk-full-size-container{width:100%;height:100%}\n"] }]
@@ -5235,10 +5419,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
5235
5419
  type: Input
5236
5420
  }], styleOptions: [{
5237
5421
  type: Input
5422
+ }], drilldownOptions: [{
5423
+ type: Input
5238
5424
  }], title: [{
5239
5425
  type: Input
5240
5426
  }], description: [{
5241
5427
  type: Input
5428
+ }], dataPointClick: [{
5429
+ type: Output
5430
+ }], dataPointContextMenu: [{
5431
+ type: Output
5242
5432
  }] } });
5243
5433
 
5244
5434
  /**
@@ -6256,6 +6446,57 @@ const textWidgetProps = widgetModelTranslator.toTextWidgetProps(widgetModel);
6256
6446
  function toTextWidgetProps(widgetModel) {
6257
6447
  return widgetModelTranslator$1.toTextWidgetProps(widgetModel);
6258
6448
  }
6449
+ /**
6450
+ * Translates {@link WidgetModel} to {@link WidgetProps}.
6451
+ *
6452
+ * @example
6453
+ * ```html
6454
+ * <csdk-widget
6455
+ * *ngIf="widgetProps"
6456
+ * [id]="widgetProps.id"
6457
+ * [widgetType]="widgetProps.widgetType"
6458
+ * [chartType]="widgetProps.chartType"
6459
+ * [dataSource]="widgetProps.dataSource"
6460
+ * [dataOptions]="widgetProps.dataOptions"
6461
+ * [filters]="widgetProps.filters"
6462
+ * [highlights]="widgetProps.highlights"
6463
+ * [styleOptions]="widgetProps.styleOptions"
6464
+ * [title]="widgetProps.title"
6465
+ * [description]="widgetProps.description"
6466
+ * />
6467
+ * ```
6468
+ *
6469
+ * ```ts
6470
+ * import { Component } from '@angular/core';
6471
+ * import {
6472
+ * type WidgetProps,
6473
+ * WidgetService,
6474
+ * widgetModelTranslator,
6475
+ * } from '@sisense/sdk-ui-angular';
6476
+ *
6477
+ * @Component({
6478
+ * selector: 'app-example',
6479
+ * templateUrl: './example.component.html',
6480
+ * styleUrls: ['./example.component.scss'],
6481
+ * })
6482
+ * export class ExampleComponent {
6483
+ * widgetProps: WidgetProps | null = null;
6484
+ *
6485
+ * constructor(private widgetService: WidgetService) {}
6486
+ *
6487
+ * async ngOnInit(): Promise<void> {
6488
+ * const widgetModel = await widgetService.getWidgetModel({
6489
+ * dashboardOid: 'your-dashboard-oid',
6490
+ * widgetOid: 'your-widget-oid'
6491
+ * });
6492
+ * this.widgetProps = widgetModelTranslator.toWidgetProps(widgetModel);
6493
+ * }
6494
+ * }
6495
+ * ```
6496
+ */
6497
+ function toWidgetProps(widgetModel) {
6498
+ return widgetModelTranslator$1.toWidgetProps(widgetModel);
6499
+ }
6259
6500
 
6260
6501
  var widgetModelTranslator = /*#__PURE__*/Object.freeze({
6261
6502
  __proto__: null,
@@ -6266,7 +6507,8 @@ var widgetModelTranslator = /*#__PURE__*/Object.freeze({
6266
6507
  toPivotTableProps: toPivotTableProps,
6267
6508
  toPivotTableWidgetProps: toPivotTableWidgetProps,
6268
6509
  toTableProps: toTableProps,
6269
- toTextWidgetProps: toTextWidgetProps
6510
+ toTextWidgetProps: toTextWidgetProps,
6511
+ toWidgetProps: toWidgetProps
6270
6512
  });
6271
6513
 
6272
6514
  /**