@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.
- package/dist/esm2020/lib/components/charts/pivot-table.component.mjs +21 -3
- package/dist/esm2020/lib/components/widgets/pivot-table-widget.component.mjs +24 -3
- package/dist/esm2020/lib/components/widgets/widget.component.mjs +1 -1
- package/dist/esm2020/lib/decorators/decorators.module.mjs +2 -2
- package/dist/esm2020/lib/helpers/dashboard-props-preact-translator.mjs +1 -1
- package/dist/esm2020/lib/helpers/widget-props-preact-translator.mjs +5 -2
- package/dist/esm2020/lib/sdk-ui-core-exports.mjs +1 -1
- package/dist/esm2020/lib/services/dashboard.service.mjs +18 -6
- package/dist/esm2020/lib/services/widget.service.mjs +146 -6
- package/dist/esm2020/lib/types/chart-event-props.mjs +1 -1
- package/dist/esm2020/lib/types/data-point.mjs +1 -1
- package/dist/esm2020/lib/utilities/widget-model-translator.mjs +52 -1
- package/dist/esm2020/public-api.mjs +1 -1
- package/dist/esm2020/version.mjs +2 -2
- package/dist/fesm2015/sisense-sdk-ui-angular.mjs +1566 -1324
- package/dist/fesm2015/sisense-sdk-ui-angular.mjs.map +1 -1
- package/dist/fesm2020/sisense-sdk-ui-angular.mjs +1372 -1130
- package/dist/fesm2020/sisense-sdk-ui-angular.mjs.map +1 -1
- package/dist/lib/components/charts/pivot-table.component.d.ts +16 -3
- package/dist/lib/components/widgets/pivot-table-widget.component.d.ts +22 -3
- package/dist/lib/components/widgets/widget.component.d.ts +8 -4
- package/dist/lib/decorators/decorators.module.d.ts +1 -1
- package/dist/lib/helpers/dashboard-props-preact-translator.d.ts +1 -1
- package/dist/lib/helpers/widget-props-preact-translator.d.ts +1 -1
- package/dist/lib/sdk-ui-core-exports.d.ts +1 -1
- package/dist/lib/services/dashboard.service.d.ts +13 -5
- package/dist/lib/services/widget.service.d.ts +100 -2
- package/dist/lib/types/chart-event-props.d.ts +15 -1
- package/dist/lib/types/data-point.d.ts +13 -2
- package/dist/lib/utilities/widget-model-translator.d.ts +50 -1
- package/dist/package.json +1 -1
- package/dist/public-api.d.ts +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +4 -4
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { InjectionToken, Injectable, Optional, Inject,
|
|
3
|
-
import { DataObserver, CustomThemeProvider, CustomSisenseContextProvider, CustomWidgetsProviderAdapter, createClientApplication, TabberButtonsWidget, createWrapperElement, getDashboardModel, getDashboardModels, HookAdapter, useComposedDashboardInternal, createHookApiFacade, useGetFilterMembers, getHierarchyModels, executeQuery, executeQueryByWidgetId, executePivotQuery, useExecuteCsvQueryInternal, useExecuteCustomWidgetQueryInternal, getWidgetModel,
|
|
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.
|
|
288
|
+
var packageVersion = '2.18.1';
|
|
289
289
|
|
|
290
|
-
|
|
291
|
-
|
|
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
|
-
|
|
373
|
-
|
|
374
|
-
i0.ɵɵ
|
|
375
|
-
|
|
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
|
+
DecoratorsModule.ɵmod = 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
|
-
|
|
301
|
+
declarations: [],
|
|
302
|
+
exports: [],
|
|
378
303
|
}]
|
|
379
|
-
}], ctorParameters: function () { return [{ type:
|
|
304
|
+
}], ctorParameters: function () { return [{ type: SisenseContextService }]; } });
|
|
380
305
|
|
|
381
|
-
function
|
|
382
|
-
const
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
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
|
|
422
|
-
return {
|
|
423
|
-
|
|
424
|
-
|
|
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
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
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
|
-
*
|
|
347
|
+
* Token used to inject {@link ThemeConfig} into your application
|
|
436
348
|
*
|
|
437
|
-
*
|
|
349
|
+
* @example
|
|
438
350
|
*
|
|
439
|
-
* @
|
|
440
|
-
*
|
|
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
|
-
|
|
443
|
-
|
|
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
|
-
|
|
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
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
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
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
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
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
TrackableService(['
|
|
553
|
-
],
|
|
554
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type:
|
|
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
|
-
*
|
|
459
|
+
* An Angular component used for easily switching chart types or rendering multiple series of different chart types.
|
|
563
460
|
*
|
|
564
|
-
* @
|
|
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
|
-
|
|
567
|
-
constructor(sisenseContextService) {
|
|
568
|
-
this.sisenseContextService = sisenseContextService;
|
|
569
|
-
}
|
|
510
|
+
class ChartComponent {
|
|
570
511
|
/**
|
|
571
|
-
*
|
|
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
|
-
*
|
|
580
|
-
*
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
514
|
+
* @param sisenseContextService - Sisense context service
|
|
515
|
+
* @param themeService - Theme service
|
|
516
|
+
*/
|
|
517
|
+
constructor(
|
|
518
|
+
/**
|
|
519
|
+
* Sisense context service
|
|
584
520
|
*
|
|
585
|
-
*
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
*
|
|
590
|
-
* ```
|
|
521
|
+
* @category Constructor
|
|
522
|
+
*/
|
|
523
|
+
sisenseContextService,
|
|
524
|
+
/**
|
|
525
|
+
* Theme service
|
|
591
526
|
*
|
|
592
|
-
* @
|
|
593
|
-
* @returns Promise that resolves to the filter members data
|
|
527
|
+
* @category Constructor
|
|
594
528
|
*/
|
|
595
|
-
|
|
596
|
-
|
|
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
|
-
*
|
|
699
|
-
*
|
|
700
|
-
* @param params - Parameters to identify the target widget
|
|
701
|
-
* @returns Query result
|
|
556
|
+
* @internal
|
|
702
557
|
*/
|
|
703
|
-
|
|
704
|
-
|
|
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
|
-
*
|
|
713
|
-
*
|
|
714
|
-
* @param params - Pivot query parameters
|
|
715
|
-
* @return Pivot query result
|
|
562
|
+
* @internal
|
|
716
563
|
*/
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
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
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
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
|
-
*
|
|
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
|
-
|
|
772
|
-
|
|
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
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
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
|
+
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"] });
|
|
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
|
-
*
|
|
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
|
-
* @
|
|
813
|
-
*
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
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
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
}
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
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
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
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
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
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
|
-
*
|
|
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
|
-
*
|
|
905
|
-
*
|
|
906
|
-
*
|
|
907
|
-
*
|
|
908
|
-
*
|
|
909
|
-
*
|
|
910
|
-
*
|
|
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: '
|
|
791
|
+
chartType: 'arearange' as ChartType,
|
|
1208
792
|
dataSet: DM.DataSource,
|
|
1209
793
|
dataOptions: {
|
|
1210
|
-
category: [DM.
|
|
1211
|
-
value: [
|
|
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
|
-
* @
|
|
2478
|
-
*
|
|
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
|
|
2528
|
-
constructor() {
|
|
2529
|
-
|
|
2530
|
-
|
|
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
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
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
|
-
|
|
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
|
-
}],
|
|
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
|
/**
|