@sisense/sdk-ui-angular 2.18.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/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 +1 -1
- package/dist/esm2020/version.mjs +2 -2
- package/dist/fesm2015/sisense-sdk-ui-angular.mjs +1636 -1636
- package/dist/fesm2015/sisense-sdk-ui-angular.mjs.map +1 -1
- package/dist/fesm2020/sisense-sdk-ui-angular.mjs +1633 -1633
- package/dist/fesm2020/sisense-sdk-ui-angular.mjs.map +1 -1
- 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/package.json +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, useJtdWidget,
|
|
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,1024 +285,843 @@ 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.18.
|
|
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({
|
|
396
|
-
point,
|
|
397
|
-
nativeEvent,
|
|
398
|
-
})
|
|
399
|
-
: undefined,
|
|
400
|
-
onDataPointsSelected: dataPointsSelect
|
|
401
|
-
? (...[points, nativeEvent]) => dataPointsSelect({ points, nativeEvent })
|
|
402
|
-
: undefined,
|
|
403
|
-
};
|
|
404
|
-
}
|
|
405
|
-
function translateFromPreactWidgetProps(widgetProps) {
|
|
406
|
-
const { onBeforeRender, onDataReady, onBeforeMenuOpen, onDataPointClick, onDataPointContextMenu, onDataPointsSelected, ...commonWidgetProps } = widgetProps;
|
|
407
|
-
return {
|
|
408
|
-
...commonWidgetProps,
|
|
409
|
-
beforeRender: onBeforeRender,
|
|
410
|
-
dataReady: onDataReady,
|
|
411
|
-
beforeMenuOpen: onBeforeMenuOpen,
|
|
412
|
-
dataPointClick: onDataPointClick
|
|
413
|
-
? ({ point, nativeEvent }) => onDataPointClick(point, nativeEvent)
|
|
414
|
-
: undefined,
|
|
415
|
-
dataPointContextMenu: onDataPointContextMenu
|
|
416
|
-
? ({ point, nativeEvent }) => onDataPointContextMenu(point, nativeEvent)
|
|
417
|
-
: undefined,
|
|
418
|
-
dataPointsSelect: onDataPointsSelected
|
|
419
|
-
? ({ points, nativeEvent }) => onDataPointsSelected(points, nativeEvent)
|
|
420
|
-
: 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);
|
|
421
311
|
};
|
|
312
|
+
return descriptor;
|
|
422
313
|
}
|
|
423
|
-
|
|
424
|
-
function
|
|
425
|
-
return {
|
|
426
|
-
|
|
427
|
-
|
|
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
|
+
});
|
|
428
326
|
};
|
|
429
327
|
}
|
|
430
|
-
function
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
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
|
+
}
|
|
435
344
|
}
|
|
436
345
|
|
|
437
346
|
/**
|
|
438
|
-
*
|
|
347
|
+
* Token used to inject {@link ThemeConfig} into your application
|
|
439
348
|
*
|
|
440
|
-
*
|
|
349
|
+
* @example
|
|
441
350
|
*
|
|
442
|
-
* @
|
|
443
|
-
*
|
|
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
|
|
444
379
|
*/
|
|
445
|
-
|
|
446
|
-
|
|
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) {
|
|
447
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
|
+
});
|
|
448
406
|
}
|
|
449
|
-
|
|
450
|
-
* Retrieves an existing dashboard model from the Sisense instance.
|
|
451
|
-
*
|
|
452
|
-
* @param dashboardOid - Identifier of the dashboard
|
|
453
|
-
* @param options - Advanced configuration options
|
|
454
|
-
* @returns Dashboard model
|
|
455
|
-
*/
|
|
456
|
-
async getDashboardModel(dashboardOid, options) {
|
|
407
|
+
async initThemeSettings(theme) {
|
|
457
408
|
const app = await this.sisenseContextService.getApp();
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
*/
|
|
466
|
-
async getDashboardModels(options) {
|
|
467
|
-
const app = await this.sisenseContextService.getApp();
|
|
468
|
-
return getDashboardModels(app.httpClient, options);
|
|
409
|
+
// apply system theme settings first
|
|
410
|
+
await this.applyThemeSettings(app.settings.serverThemeSettings);
|
|
411
|
+
if (theme) {
|
|
412
|
+
// Manually tracks theme update during initialization as execution of updateThemeSettings for consistency.
|
|
413
|
+
track('sdkAngularServiceMethodExecuted', 'ThemeService.updateThemeSettings');
|
|
414
|
+
await this.applyThemeSettings(theme);
|
|
415
|
+
}
|
|
469
416
|
}
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
*ngFor="let filter of getDashboardFilters(dashboard); trackBy: trackByIndex"
|
|
481
|
-
[filter]="filter"
|
|
482
|
-
/>
|
|
483
|
-
<csdk-widget
|
|
484
|
-
*ngFor="let widget of dashboard.widgets; trackBy: trackByIndex"
|
|
485
|
-
[id]="widget.id"
|
|
486
|
-
[widgetType]="widget.widgetType"
|
|
487
|
-
[chartType]="widget.chartType"
|
|
488
|
-
[customWidgetType]="widget.customWidgetType"
|
|
489
|
-
[dataSource]="widget.dataSource"
|
|
490
|
-
[dataOptions]="widget.dataOptions"
|
|
491
|
-
[filters]="widget.filters"
|
|
492
|
-
[highlights]="widget.highlights"
|
|
493
|
-
[styleOptions]="widget.styleOptions"
|
|
494
|
-
[drilldownOptions]="widget.drilldownOptions"
|
|
495
|
-
[title]="widget.title"
|
|
496
|
-
[description]="widget.description"
|
|
497
|
-
[beforeMenuOpen]="widget.beforeMenuOpen"
|
|
498
|
-
(dataPointClick)="widget.dataPointClick?.($event)"
|
|
499
|
-
(dataPointContextMenu)="widget.dataPointContextMenu?.($event)"
|
|
500
|
-
(dataPointsSelect)="widget.dataPointsSelect?.($event)"
|
|
501
|
-
/>
|
|
502
|
-
</div>
|
|
503
|
-
* ```
|
|
504
|
-
*
|
|
505
|
-
* ```ts
|
|
506
|
-
// Component behavior in example.component.ts
|
|
507
|
-
import { Component, OnDestroy } from '@angular/core';
|
|
508
|
-
import { BehaviorSubject } from 'rxjs';
|
|
509
|
-
import { DashboardService, type DashboardProps } from '@sisense/sdk-ui-angular';
|
|
510
|
-
|
|
511
|
-
@Component({
|
|
512
|
-
selector: 'example',
|
|
513
|
-
templateUrl: './example.component.html',
|
|
514
|
-
styleUrls: ['./example.component.scss'],
|
|
515
|
-
})
|
|
516
|
-
export class ExampleComponent implements OnDestroy {
|
|
517
|
-
dashboard$: BehaviorSubject<DashboardProps> | undefined;
|
|
518
|
-
private composedDashboard: ReturnType<DashboardService['createComposedDashboard']> | undefined;
|
|
519
|
-
|
|
520
|
-
constructor(private dashboardService: DashboardService) {}
|
|
521
|
-
|
|
522
|
-
ngOnInit() {
|
|
523
|
-
const initialDashboard: DashboardProps = { ... };
|
|
524
|
-
this.composedDashboard = this.dashboardService.createComposedDashboard(initialDashboard);
|
|
525
|
-
this.dashboard$ = this.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);
|
|
526
427
|
}
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
this.composedDashboard?.destroy();
|
|
428
|
+
catch (error) {
|
|
429
|
+
this.themeSettings$.error(error);
|
|
530
430
|
}
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
* @returns Reactive composed dashboard object and API methods for interacting with it.
|
|
540
|
-
* The returned object includes a `destroy()` method that should be called when
|
|
541
|
-
* the dashboard is no longer needed to prevent memory leaks (e.g., in `ngOnDestroy`).
|
|
542
|
-
*/
|
|
543
|
-
createComposedDashboard(initialDashboard, options = {}) {
|
|
544
|
-
const hookAdapter = new HookAdapter((useComposedDashboardInternal), [createSisenseContextConnector(this.sisenseContextService)]);
|
|
545
|
-
const dashboard$ = new BehaviorSubject(initialDashboard);
|
|
546
|
-
hookAdapter.subscribe(({ dashboard }) => {
|
|
547
|
-
dashboard$.next(translateFromPreactDashboardProps(dashboard));
|
|
548
|
-
});
|
|
549
|
-
hookAdapter.run(translateToPreactDashboardProps(initialDashboard), options);
|
|
550
|
-
const setFilters = createHookApiFacade(hookAdapter, 'setFilters', true);
|
|
551
|
-
const setWidgetsLayout = createHookApiFacade(hookAdapter, 'setWidgetsLayout', true);
|
|
552
|
-
const destroy = () => {
|
|
553
|
-
hookAdapter.destroy();
|
|
554
|
-
dashboard$.complete();
|
|
555
|
-
};
|
|
556
|
-
return {
|
|
557
|
-
dashboard$,
|
|
558
|
-
setFilters,
|
|
559
|
-
setWidgetsLayout,
|
|
560
|
-
destroy,
|
|
561
|
-
};
|
|
431
|
+
}
|
|
432
|
+
/** @internal */
|
|
433
|
+
getThemeSettings() {
|
|
434
|
+
return this.themeSettings$.asObservable();
|
|
435
|
+
}
|
|
436
|
+
async updateThemeSettings(theme) {
|
|
437
|
+
await this.initializationPromise;
|
|
438
|
+
await this.applyThemeSettings(theme);
|
|
562
439
|
}
|
|
563
440
|
};
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
TrackableService(['
|
|
568
|
-
],
|
|
569
|
-
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: [{
|
|
570
447
|
type: Injectable,
|
|
571
448
|
args: [{
|
|
572
449
|
providedIn: 'root',
|
|
573
450
|
}]
|
|
574
|
-
}], 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
|
+
}] }]; } });
|
|
575
457
|
|
|
576
458
|
/**
|
|
577
|
-
*
|
|
459
|
+
* An Angular component used for easily switching chart types or rendering multiple series of different chart types.
|
|
578
460
|
*
|
|
579
|
-
* @
|
|
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
|
|
580
509
|
*/
|
|
581
|
-
|
|
582
|
-
constructor(sisenseContextService) {
|
|
583
|
-
this.sisenseContextService = sisenseContextService;
|
|
584
|
-
}
|
|
510
|
+
class ChartComponent {
|
|
585
511
|
/**
|
|
586
|
-
*
|
|
587
|
-
*
|
|
588
|
-
* Those members can be used to display a list of members in a third-party filter component such as Material UI Select.
|
|
589
|
-
*
|
|
590
|
-
* ## Example
|
|
591
|
-
*
|
|
592
|
-
* Retrieve selected members from a Filter on Country of the Sample ECommerce data model.
|
|
512
|
+
* Constructor for the `Chart` component.
|
|
593
513
|
*
|
|
594
|
-
*
|
|
595
|
-
*
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
514
|
+
* @param sisenseContextService - Sisense context service
|
|
515
|
+
* @param themeService - Theme service
|
|
516
|
+
*/
|
|
517
|
+
constructor(
|
|
518
|
+
/**
|
|
519
|
+
* Sisense context service
|
|
599
520
|
*
|
|
600
|
-
*
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
*
|
|
605
|
-
* ```
|
|
521
|
+
* @category Constructor
|
|
522
|
+
*/
|
|
523
|
+
sisenseContextService,
|
|
524
|
+
/**
|
|
525
|
+
* Theme service
|
|
606
526
|
*
|
|
607
|
-
* @
|
|
608
|
-
* @returns Promise that resolves to the filter members data
|
|
527
|
+
* @category Constructor
|
|
609
528
|
*/
|
|
610
|
-
|
|
611
|
-
|
|
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, [
|
|
612
551
|
createSisenseContextConnector(this.sisenseContextService),
|
|
552
|
+
createThemeContextConnector(this.themeService),
|
|
613
553
|
]);
|
|
614
|
-
const resultPromise = new Promise((resolve, reject) => {
|
|
615
|
-
hookAdapter.subscribe((res) => {
|
|
616
|
-
const { isError, isSuccess, error } = res;
|
|
617
|
-
if (isError) {
|
|
618
|
-
reject(error);
|
|
619
|
-
}
|
|
620
|
-
else if (isSuccess) {
|
|
621
|
-
resolve(res.data);
|
|
622
|
-
}
|
|
623
|
-
});
|
|
624
|
-
});
|
|
625
|
-
hookAdapter.run(params);
|
|
626
|
-
return resultPromise.finally(() => {
|
|
627
|
-
hookAdapter.destroy();
|
|
628
|
-
});
|
|
629
|
-
}
|
|
630
|
-
};
|
|
631
|
-
FilterService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: FilterService, deps: [{ token: SisenseContextService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
632
|
-
FilterService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: FilterService, providedIn: 'root' });
|
|
633
|
-
FilterService = __decorate([
|
|
634
|
-
TrackableService(['getFilterMembers'])
|
|
635
|
-
], FilterService);
|
|
636
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: FilterService, decorators: [{
|
|
637
|
-
type: Injectable,
|
|
638
|
-
args: [{
|
|
639
|
-
providedIn: 'root',
|
|
640
|
-
}]
|
|
641
|
-
}], ctorParameters: function () { return [{ type: SisenseContextService }]; } });
|
|
642
|
-
|
|
643
|
-
/**
|
|
644
|
-
* Service for working with Sisense Fusion hierarchies.
|
|
645
|
-
*
|
|
646
|
-
* @group Fusion Assets
|
|
647
|
-
* @fusionEmbed
|
|
648
|
-
*/
|
|
649
|
-
let HierarchyService = class HierarchyService {
|
|
650
|
-
constructor(sisenseContextService) {
|
|
651
|
-
this.sisenseContextService = sisenseContextService;
|
|
652
|
-
}
|
|
653
|
-
/**
|
|
654
|
-
* Retrieves existing hierarchy models from the Sisense instance.
|
|
655
|
-
*
|
|
656
|
-
* @param params - Parameters to identify the target hierarchy models
|
|
657
|
-
* @returns Hierarchy models array
|
|
658
|
-
*/
|
|
659
|
-
async getHierarchyModels(params) {
|
|
660
|
-
const app = await this.sisenseContextService.getApp();
|
|
661
|
-
return getHierarchyModels(app.httpClient, params, app.defaultDataSource);
|
|
662
|
-
}
|
|
663
|
-
};
|
|
664
|
-
HierarchyService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: HierarchyService, deps: [{ token: SisenseContextService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
665
|
-
HierarchyService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: HierarchyService, providedIn: 'root' });
|
|
666
|
-
HierarchyService = __decorate([
|
|
667
|
-
TrackableService(['getHierarchyModels'])
|
|
668
|
-
], HierarchyService);
|
|
669
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: HierarchyService, decorators: [{
|
|
670
|
-
type: Injectable,
|
|
671
|
-
args: [{
|
|
672
|
-
providedIn: 'root',
|
|
673
|
-
}]
|
|
674
|
-
}], ctorParameters: function () { return [{ type: SisenseContextService }]; } });
|
|
675
|
-
|
|
676
|
-
/**
|
|
677
|
-
* Service for executing data queries.
|
|
678
|
-
*
|
|
679
|
-
* @group Queries
|
|
680
|
-
*/
|
|
681
|
-
let QueryService = class QueryService {
|
|
682
|
-
constructor(sisenseContextService) {
|
|
683
|
-
this.sisenseContextService = sisenseContextService;
|
|
684
|
-
}
|
|
685
|
-
/**
|
|
686
|
-
* Executes a data query. If you want to display the query results, you can use
|
|
687
|
-
* them to populate Compose SDK UI elements or third party UI elements.
|
|
688
|
-
*
|
|
689
|
-
* To learn how to populate third party UI elements with query results, see the
|
|
690
|
-
* [External Charts Guide](/guides/sdk/guides/charts/guide-external-charts.html#query)
|
|
691
|
-
*
|
|
692
|
-
* @param params - Query parameters
|
|
693
|
-
* @return Query result
|
|
694
|
-
*/
|
|
695
|
-
async executeQuery(params) {
|
|
696
|
-
const { dataSource, dimensions, measures, filters, highlights, count, offset, ungroup, beforeQuery, } = params;
|
|
697
|
-
const app = await this.sisenseContextService.getApp();
|
|
698
|
-
const { filters: filterList, relations: filterRelations } = getFilterListAndRelationsJaql(filters);
|
|
699
|
-
const data = await executeQuery({
|
|
700
|
-
dataSource,
|
|
701
|
-
dimensions,
|
|
702
|
-
measures,
|
|
703
|
-
filters: filterList,
|
|
704
|
-
filterRelations,
|
|
705
|
-
highlights,
|
|
706
|
-
count,
|
|
707
|
-
offset,
|
|
708
|
-
ungroup,
|
|
709
|
-
}, app, { onBeforeQuery: beforeQuery });
|
|
710
|
-
return { data };
|
|
711
554
|
}
|
|
712
555
|
/**
|
|
713
|
-
*
|
|
714
|
-
*
|
|
715
|
-
* @param params - Parameters to identify the target widget
|
|
716
|
-
* @returns Query result
|
|
556
|
+
* @internal
|
|
717
557
|
*/
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
return executeQueryByWidgetId({
|
|
721
|
-
...params,
|
|
722
|
-
app,
|
|
723
|
-
onBeforeQuery: params.beforeQuery,
|
|
724
|
-
});
|
|
558
|
+
ngAfterViewInit() {
|
|
559
|
+
this.componentAdapter.render(this.preactRef.nativeElement, this.getPreactComponentProps());
|
|
725
560
|
}
|
|
726
561
|
/**
|
|
727
|
-
*
|
|
728
|
-
*
|
|
729
|
-
* @param params - Pivot query parameters
|
|
730
|
-
* @return Pivot query result
|
|
562
|
+
* @internal
|
|
731
563
|
*/
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
const data = await executePivotQuery({
|
|
737
|
-
dataSource,
|
|
738
|
-
rows,
|
|
739
|
-
columns,
|
|
740
|
-
values,
|
|
741
|
-
grandTotals,
|
|
742
|
-
filters: filterList,
|
|
743
|
-
filterRelations,
|
|
744
|
-
highlights,
|
|
745
|
-
count,
|
|
746
|
-
offset,
|
|
747
|
-
}, app, { onBeforeQuery: beforeQuery });
|
|
748
|
-
return { data };
|
|
564
|
+
ngOnChanges() {
|
|
565
|
+
if (this.preactRef) {
|
|
566
|
+
this.componentAdapter.render(this.preactRef.nativeElement, this.getPreactComponentProps());
|
|
567
|
+
}
|
|
749
568
|
}
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
if (isSuccess) {
|
|
765
|
-
resolve({ data });
|
|
766
|
-
}
|
|
767
|
-
else if (isError) {
|
|
768
|
-
reject(error);
|
|
769
|
-
}
|
|
770
|
-
});
|
|
771
|
-
});
|
|
772
|
-
hookAdapter.run(params);
|
|
773
|
-
return resultPromise.finally(() => {
|
|
774
|
-
hookAdapter.destroy();
|
|
775
|
-
});
|
|
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
|
+
};
|
|
776
583
|
}
|
|
777
584
|
/**
|
|
778
|
-
*
|
|
779
|
-
*
|
|
780
|
-
* This method takes custom widget props (dataSource, dataOptions, filters, etc.)
|
|
781
|
-
* and executes the appropriate data query
|
|
782
|
-
*
|
|
783
|
-
* @param params - Custom widget component props containing data source, data options, filters, etc.
|
|
784
|
-
* @returns Promise resolving to query result with formatted data
|
|
585
|
+
* @internal
|
|
785
586
|
*/
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
createSisenseContextConnector(this.sisenseContextService),
|
|
789
|
-
]);
|
|
790
|
-
const resultPromise = new Promise((resolve, reject) => {
|
|
791
|
-
hookAdapter.subscribe((res) => {
|
|
792
|
-
const { data, isSuccess, isError, error } = res;
|
|
793
|
-
if (isSuccess) {
|
|
794
|
-
resolve({ data });
|
|
795
|
-
}
|
|
796
|
-
else if (isError) {
|
|
797
|
-
reject(error);
|
|
798
|
-
}
|
|
799
|
-
});
|
|
800
|
-
});
|
|
801
|
-
hookAdapter.run(params);
|
|
802
|
-
return resultPromise.finally(() => {
|
|
803
|
-
hookAdapter.destroy();
|
|
804
|
-
});
|
|
587
|
+
ngOnDestroy() {
|
|
588
|
+
this.componentAdapter.destroy();
|
|
805
589
|
}
|
|
806
|
-
}
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
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
|
+
}] } });
|
|
823
622
|
|
|
824
623
|
/**
|
|
825
|
-
*
|
|
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.
|
|
826
626
|
*
|
|
827
|
-
* @
|
|
828
|
-
*
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
return getWidgetModel(app.httpClient, dashboardOid, widgetOid);
|
|
845
|
-
}
|
|
846
|
-
/**
|
|
847
|
-
* Adds Jump To Dashboard (JTD) functionality to widget props.
|
|
848
|
-
*
|
|
849
|
-
* Jump To Dashboard (JTD) allows users to navigate from one dashboard to another when interacting with widgets,
|
|
850
|
-
* such as clicking on chart data points or using context menus. This method is particularly useful when rendering
|
|
851
|
-
* Widget components directly (not through a Dashboard component), but you still want JTD navigation functionality.
|
|
852
|
-
*
|
|
853
|
-
* For widgets that are part of a dashboard, consider using `applyJtdConfig` or `applyJtdConfigs` instead,
|
|
854
|
-
* as they apply JTD configuration at the dashboard level rather than individual widget level.
|
|
855
|
-
*
|
|
856
|
-
* Note: dashboard-only 'includeDashboardFilters' is not supported and would just be ignored, since we do not have a dashboard in the current context.
|
|
857
|
-
*
|
|
858
|
-
* This method enhances the provided widget props with JTD navigation capabilities, including:
|
|
859
|
-
* - Click and right-click event handlers for navigation
|
|
860
|
-
* - Hyperlink styling for actionable pivot cells (when applicable)
|
|
861
|
-
* - JTD icon display in widget headers
|
|
862
|
-
* @example
|
|
863
|
-
* ```TypeScript
|
|
864
|
-
* import { Component, OnDestroy } from '@angular/core';
|
|
865
|
-
* import {
|
|
866
|
-
* WidgetService,
|
|
867
|
-
* widgetModelTranslator,
|
|
868
|
-
* type WidgetProps,
|
|
869
|
-
* } from '@sisense/sdk-ui-angular';
|
|
870
|
-
* import { BehaviorSubject } from 'rxjs';
|
|
871
|
-
*
|
|
872
|
-
* @Component({
|
|
873
|
-
* selector: 'code-example',
|
|
874
|
-
* template: `
|
|
875
|
-
* <csdk-widget
|
|
876
|
-
* *ngIf="widgetProps$ && (widgetProps$ | async) as widgetProps"
|
|
877
|
-
* [id]="widgetProps.id"
|
|
878
|
-
* [widgetType]="widgetProps.widgetType"
|
|
879
|
-
* [chartType]="widgetProps.chartType"
|
|
880
|
-
* [title]="widgetProps.title"
|
|
881
|
-
* [dataSource]="widgetProps.dataSource"
|
|
882
|
-
* [dataOptions]="widgetProps.dataOptions"
|
|
883
|
-
* [filters]="widgetProps.filters"
|
|
884
|
-
* [highlights]="widgetProps.highlights"
|
|
885
|
-
* [styleOptions]="widgetProps.styleOptions"
|
|
886
|
-
* [beforeMenuOpen]="widgetProps.beforeMenuOpen"
|
|
887
|
-
* (dataPointClick)="widgetProps.dataPointClick?.($event)"
|
|
888
|
-
* (dataPointContextMenu)="widgetProps.dataPointContextMenu?.($event)"
|
|
889
|
-
* (dataPointsSelect)="widgetProps.dataPointsSelect?.($event)"
|
|
890
|
-
* />
|
|
891
|
-
* `,
|
|
892
|
-
* })
|
|
893
|
-
* export class CodeExample implements OnDestroy {
|
|
894
|
-
* constructor(private widgetService: WidgetService) {}
|
|
895
|
-
*
|
|
896
|
-
* widgetProps$: BehaviorSubject<WidgetProps | null> | null = null;
|
|
897
|
-
* private jtdDestroy: (() => void) | null = null;
|
|
898
|
-
*
|
|
899
|
-
* async ngOnInit(): Promise<void> {
|
|
900
|
-
* const widget = await this.widgetService.getWidgetModel({
|
|
901
|
-
* dashboardOid: '65a82171719e7f004018691c',
|
|
902
|
-
* widgetOid: '65a82171719e7f004018691f',
|
|
903
|
-
* });
|
|
904
|
-
*
|
|
905
|
-
* const baseProps = widget
|
|
906
|
-
* ? widgetModelTranslator.toWidgetProps(widget)
|
|
907
|
-
* : null;
|
|
908
|
-
*
|
|
909
|
-
* if (baseProps) {
|
|
910
|
-
* const jtdConfig = {
|
|
911
|
-
* targets: [{ id: 'target-dashboard-id', caption: 'Details' }],
|
|
912
|
-
* interaction: { triggerMethod: 'rightclick' },
|
|
913
|
-
* };
|
|
914
|
-
* const jtdResult = this.widgetService.createJtdWidget(
|
|
915
|
-
* baseProps,
|
|
916
|
-
* jtdConfig,
|
|
917
|
-
* );
|
|
918
|
-
* this.widgetProps$ = jtdResult.widget$;
|
|
919
|
-
* this.jtdDestroy = jtdResult.destroy;
|
|
920
|
-
* }
|
|
921
|
-
* }
|
|
922
|
-
*
|
|
923
|
-
* ngOnDestroy(): void {
|
|
924
|
-
* this.jtdDestroy?.();
|
|
925
|
-
* }
|
|
926
|
-
* }
|
|
927
|
-
* ```
|
|
928
|
-
*
|
|
929
|
-
* @param widgetProps - Base widget props to enhance with JTD functionality
|
|
930
|
-
* @param jtdConfig - JTD configuration defining navigation targets and behavior
|
|
931
|
-
* @returns Object containing:
|
|
932
|
-
* - `widget$`: The observable that emits enhanced widget props with JTD handlers.
|
|
933
|
-
* - `destroy`: Function to clean up resources. Call this when the component is destroyed.
|
|
934
|
-
* @group Dashboards
|
|
935
|
-
*/
|
|
936
|
-
createJtdWidget(widgetProps, jtdConfig) {
|
|
937
|
-
// Create BehaviorSubject initialized with base props (or null)
|
|
938
|
-
const enhancedProps$ = new BehaviorSubject(widgetProps);
|
|
939
|
-
if (!widgetProps) {
|
|
940
|
-
return {
|
|
941
|
-
widget$: enhancedProps$,
|
|
942
|
-
destroy: () => {
|
|
943
|
-
enhancedProps$.complete();
|
|
944
|
-
},
|
|
945
|
-
};
|
|
946
|
-
}
|
|
947
|
-
// Create HookAdapter with useJtdWidget hook and context connectors
|
|
948
|
-
const hookAdapter = new HookAdapter(useJtdWidget, [
|
|
949
|
-
createSisenseContextConnector(this.sisenseContextService),
|
|
950
|
-
createThemeContextConnector(this.themeService),
|
|
951
|
-
]);
|
|
952
|
-
// Convert Angular props to preact props
|
|
953
|
-
const preactProps = translateToPreactWidgetProps(widgetProps);
|
|
954
|
-
// Subscribe to hook adapter results and capture the subscription
|
|
955
|
-
const hookAdapterSubscription = hookAdapter.subscribe((enhancedPreactProps) => {
|
|
956
|
-
if (enhancedPreactProps) {
|
|
957
|
-
// Convert back to Angular props
|
|
958
|
-
const angularProps = translateFromPreactWidgetProps(enhancedPreactProps);
|
|
959
|
-
enhancedProps$.next(angularProps);
|
|
960
|
-
}
|
|
961
|
-
else {
|
|
962
|
-
enhancedProps$.next(null);
|
|
963
|
-
}
|
|
964
|
-
});
|
|
965
|
-
// Run the hook with widget props and JTD config
|
|
966
|
-
// This will trigger the subscription above asynchronously when React contexts are ready
|
|
967
|
-
hookAdapter.run(preactProps, jtdConfig);
|
|
968
|
-
// Return the BehaviorSubject and destroy function for cleanup
|
|
969
|
-
return {
|
|
970
|
-
widget$: enhancedProps$,
|
|
971
|
-
destroy: () => {
|
|
972
|
-
// Unsubscribe from hook adapter
|
|
973
|
-
hookAdapterSubscription.unsubscribe();
|
|
974
|
-
// Destroy the hook adapter to clean up React components and contexts
|
|
975
|
-
hookAdapter.destroy();
|
|
976
|
-
// Complete the BehaviorSubject to release subscribers and avoid leaks
|
|
977
|
-
enhancedProps$.complete();
|
|
978
|
-
},
|
|
979
|
-
};
|
|
980
|
-
}
|
|
981
|
-
};
|
|
982
|
-
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 });
|
|
983
|
-
WidgetService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: WidgetService, providedIn: 'root' });
|
|
984
|
-
WidgetService = __decorate([
|
|
985
|
-
TrackableService(['getWidgetModel', 'createJtdWidget'])
|
|
986
|
-
], WidgetService);
|
|
987
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: WidgetService, decorators: [{
|
|
988
|
-
type: Injectable,
|
|
989
|
-
args: [{
|
|
990
|
-
providedIn: 'root',
|
|
991
|
-
}]
|
|
992
|
-
}], ctorParameters: function () { return [{ type: SisenseContextService }, { type: ThemeService }]; } });
|
|
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';
|
|
993
644
|
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
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
|
+
};
|
|
662
|
+
|
|
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
|
+
}
|
|
672
|
+
}
|
|
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';
|
|
997
699
|
}
|
|
998
700
|
}
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
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,
|
|
1004
719
|
args: [{
|
|
1005
|
-
|
|
1006
|
-
|
|
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
|
+
`,
|
|
1007
736
|
}]
|
|
1008
|
-
}],
|
|
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
|
+
}] } });
|
|
1009
758
|
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
}
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
759
|
+
/**
|
|
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.
|
|
763
|
+
*
|
|
764
|
+
* @example
|
|
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
|
+
* />
|
|
775
|
+
* ```
|
|
776
|
+
* ```ts
|
|
777
|
+
import { Component } from '@angular/core';
|
|
778
|
+
import { measureFactory, filterFactory, Filter } from '@sisense/sdk-data';
|
|
779
|
+
import * as DM from '../../assets/sample-healthcare-model';
|
|
780
|
+
import type { ChartType, RangeChartDataOptions } from '@sisense/sdk-ui-angular';
|
|
781
|
+
|
|
782
|
+
@Component({
|
|
783
|
+
selector: 'app-analytics',
|
|
784
|
+
templateUrl: './analytics.component.html',
|
|
785
|
+
styleUrls: ['./analytics.component.scss'],
|
|
786
|
+
})
|
|
787
|
+
export class AnalyticsComponent {
|
|
788
|
+
DM = DM;
|
|
789
|
+
filters = [filterFactory.members(DM.Divisions.Divison_name, ['Cardiology', 'Neurology'])];
|
|
790
|
+
chart = {
|
|
791
|
+
chartType: 'arearange' as ChartType,
|
|
792
|
+
dataSet: DM.DataSource,
|
|
793
|
+
dataOptions: {
|
|
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
|
+
),
|
|
1043
806
|
}
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
807
|
+
],
|
|
808
|
+
breakBy: [],
|
|
809
|
+
} as RangeChartDataOptions,
|
|
810
|
+
};
|
|
811
|
+
|
|
812
|
+
onBeforeRender(options: any) {
|
|
813
|
+
console.log('beforeRender');
|
|
814
|
+
console.log(options);
|
|
815
|
+
return options;
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
logArguments(...args: any[]) {
|
|
819
|
+
console.log(args);
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
* ```
|
|
823
|
+
* <img src="media://angular-area-range-chart-example.png" width="800px" />
|
|
824
|
+
* @group Charts
|
|
825
|
+
*/
|
|
826
|
+
class AreaRangeChartComponent {
|
|
827
|
+
constructor() {
|
|
828
|
+
/**
|
|
829
|
+
* {@inheritDoc @sisense/sdk-ui!AreaRangeChartProps.onDataPointClick}
|
|
830
|
+
*
|
|
831
|
+
* @category Callbacks
|
|
832
|
+
*/
|
|
833
|
+
this.dataPointClick = new EventEmitter();
|
|
834
|
+
/**
|
|
835
|
+
* {@inheritDoc @sisense/sdk-ui!AreaRangeChartProps.onDataPointContextMenu}
|
|
836
|
+
*
|
|
837
|
+
* @category Callbacks
|
|
838
|
+
*/
|
|
839
|
+
this.dataPointContextMenu = new EventEmitter();
|
|
840
|
+
/**
|
|
841
|
+
* {@inheritDoc @sisense/sdk-ui!AreaRangeChartProps.onDataPointsSelected}
|
|
842
|
+
*
|
|
843
|
+
* @category Callbacks
|
|
844
|
+
*/
|
|
845
|
+
this.dataPointsSelect = new EventEmitter();
|
|
846
|
+
/** @internal */
|
|
847
|
+
this.chartType = 'arearange';
|
|
1047
848
|
}
|
|
1048
849
|
}
|
|
850
|
+
AreaRangeChartComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: AreaRangeChartComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
851
|
+
AreaRangeChartComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: AreaRangeChartComponent, selector: "csdk-area-range-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: `
|
|
852
|
+
<csdk-chart
|
|
853
|
+
[chartType]="chartType"
|
|
854
|
+
[dataSet]="dataSet"
|
|
855
|
+
[dataOptions]="dataOptions"
|
|
856
|
+
[filters]="filters"
|
|
857
|
+
[highlights]="highlights"
|
|
858
|
+
[styleOptions]="styleOptions"
|
|
859
|
+
[beforeRender]="beforeRender"
|
|
860
|
+
[dataReady]="dataReady"
|
|
861
|
+
(dataPointClick)="dataPointClick.emit($any($event))"
|
|
862
|
+
(dataPointContextMenu)="dataPointContextMenu.emit($any($event))"
|
|
863
|
+
(dataPointsSelect)="dataPointsSelect.emit($any($event))"
|
|
864
|
+
/>
|
|
865
|
+
`, isInline: true, dependencies: [{ kind: "component", type: ChartComponent, selector: "csdk-chart", inputs: ["chartType", "dataSet", "dataOptions", "filters", "highlights", "styleOptions", "beforeRender", "dataReady"], outputs: ["dataPointClick", "dataPointContextMenu", "dataPointsSelect"] }] });
|
|
866
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: AreaRangeChartComponent, decorators: [{
|
|
867
|
+
type: Component,
|
|
868
|
+
args: [{
|
|
869
|
+
selector: 'csdk-area-range-chart',
|
|
870
|
+
template: `
|
|
871
|
+
<csdk-chart
|
|
872
|
+
[chartType]="chartType"
|
|
873
|
+
[dataSet]="dataSet"
|
|
874
|
+
[dataOptions]="dataOptions"
|
|
875
|
+
[filters]="filters"
|
|
876
|
+
[highlights]="highlights"
|
|
877
|
+
[styleOptions]="styleOptions"
|
|
878
|
+
[beforeRender]="beforeRender"
|
|
879
|
+
[dataReady]="dataReady"
|
|
880
|
+
(dataPointClick)="dataPointClick.emit($any($event))"
|
|
881
|
+
(dataPointContextMenu)="dataPointContextMenu.emit($any($event))"
|
|
882
|
+
(dataPointsSelect)="dataPointsSelect.emit($any($event))"
|
|
883
|
+
/>
|
|
884
|
+
`,
|
|
885
|
+
}]
|
|
886
|
+
}], propDecorators: { dataSet: [{
|
|
887
|
+
type: Input
|
|
888
|
+
}], dataOptions: [{
|
|
889
|
+
type: Input
|
|
890
|
+
}], filters: [{
|
|
891
|
+
type: Input
|
|
892
|
+
}], highlights: [{
|
|
893
|
+
type: Input
|
|
894
|
+
}], styleOptions: [{
|
|
895
|
+
type: Input
|
|
896
|
+
}], beforeRender: [{
|
|
897
|
+
type: Input
|
|
898
|
+
}], dataReady: [{
|
|
899
|
+
type: Input
|
|
900
|
+
}], dataPointClick: [{
|
|
901
|
+
type: Output
|
|
902
|
+
}], dataPointContextMenu: [{
|
|
903
|
+
type: Output
|
|
904
|
+
}], dataPointsSelect: [{
|
|
905
|
+
type: Output
|
|
906
|
+
}] } });
|
|
1049
907
|
|
|
1050
908
|
/**
|
|
1051
|
-
*
|
|
909
|
+
* An Angular component that allows to visualize geographical data as polygons on a map.
|
|
1052
910
|
*
|
|
1053
911
|
* @example
|
|
1054
|
-
*
|
|
1055
|
-
*
|
|
912
|
+
* ```html
|
|
913
|
+
* <csdk-areamap-chart
|
|
914
|
+
* [dataSet]="areamapChart.dataSet"
|
|
915
|
+
* [dataOptions]="areamapChart.dataOptions"
|
|
916
|
+
* [styleOptions]="areamapChart.styleOptions"
|
|
917
|
+
* (dataPointClick)="logArguments($event)"
|
|
918
|
+
* />
|
|
919
|
+
* ```
|
|
1056
920
|
*
|
|
1057
921
|
* ```ts
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
*
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
922
|
+
import { Component } from '@angular/core';
|
|
923
|
+
import { measureFactory } from '@sisense/sdk-data';
|
|
924
|
+
import * as DM from '../../assets/sample-ecommerce';
|
|
925
|
+
|
|
926
|
+
@Component({
|
|
927
|
+
selector: 'app-analytics',
|
|
928
|
+
templateUrl: './analytics.component.html',
|
|
929
|
+
styleUrls: ['./analytics.component.scss'],
|
|
930
|
+
})
|
|
931
|
+
export class AnalyticsComponent {
|
|
932
|
+
areamapChart = {
|
|
933
|
+
dataSet: DM.DataSource,
|
|
934
|
+
dataOptions: {
|
|
935
|
+
geo: [DM.Country.Country],
|
|
936
|
+
color: [measureFactory.sum(DM.Commerce.Revenue, 'Color by Revenue')],
|
|
937
|
+
} as AreamapChartDataOptions,
|
|
938
|
+
styleOptions: {
|
|
939
|
+
mapType: 'world',
|
|
940
|
+
} as AreamapStyleOptions,
|
|
941
|
+
};
|
|
942
|
+
|
|
943
|
+
logArguments(...args: any[]) {
|
|
944
|
+
console.log(args);
|
|
945
|
+
}
|
|
946
|
+
}
|
|
1081
947
|
* ```
|
|
1082
|
-
*
|
|
1083
|
-
|
|
1084
|
-
const THEME_CONFIG_TOKEN = new InjectionToken('theme configuration');
|
|
1085
|
-
/**
|
|
1086
|
-
* Service for working with Sisense Fusion themes.
|
|
1087
|
-
*
|
|
1088
|
-
* If no theme service is used, the current Fusion theme is applied by default.
|
|
1089
|
-
*
|
|
1090
|
-
* @group Contexts
|
|
948
|
+
* <img src="media://angular-areamap-chart-example.png" width="800px" />
|
|
949
|
+
* @group Charts
|
|
1091
950
|
*/
|
|
1092
|
-
|
|
1093
|
-
constructor(
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
// Subscribe to new app values
|
|
1103
|
-
.subscribe({
|
|
1104
|
-
next: ({ app }) => {
|
|
1105
|
-
if (app) {
|
|
1106
|
-
this.initializationPromise = this.applyThemeSettings(app.settings.serverThemeSettings);
|
|
1107
|
-
}
|
|
1108
|
-
},
|
|
1109
|
-
});
|
|
1110
|
-
}
|
|
1111
|
-
async initThemeSettings(theme) {
|
|
1112
|
-
const app = await this.sisenseContextService.getApp();
|
|
1113
|
-
// apply system theme settings first
|
|
1114
|
-
await this.applyThemeSettings(app.settings.serverThemeSettings);
|
|
1115
|
-
if (theme) {
|
|
1116
|
-
// Manually tracks theme update during initialization as execution of updateThemeSettings for consistency.
|
|
1117
|
-
track('sdkAngularServiceMethodExecuted', 'ThemeService.updateThemeSettings');
|
|
1118
|
-
await this.applyThemeSettings(theme);
|
|
1119
|
-
}
|
|
1120
|
-
}
|
|
1121
|
-
async applyThemeSettings(theme) {
|
|
1122
|
-
try {
|
|
1123
|
-
const app = await this.sisenseContextService.getApp();
|
|
1124
|
-
const isThemeOid = typeof theme === 'string';
|
|
1125
|
-
let userThemeSettings = theme;
|
|
1126
|
-
if (isThemeOid) {
|
|
1127
|
-
userThemeSettings = await getThemeSettingsByOid(theme, app.httpClient);
|
|
1128
|
-
}
|
|
1129
|
-
const mergedThemeSettings = merge.withOptions({ mergeArrays: false }, this.themeSettings$.value, userThemeSettings);
|
|
1130
|
-
this.themeSettings$.next(mergedThemeSettings);
|
|
1131
|
-
}
|
|
1132
|
-
catch (error) {
|
|
1133
|
-
this.themeSettings$.error(error);
|
|
1134
|
-
}
|
|
1135
|
-
}
|
|
1136
|
-
/** @internal */
|
|
1137
|
-
getThemeSettings() {
|
|
1138
|
-
return this.themeSettings$.asObservable();
|
|
1139
|
-
}
|
|
1140
|
-
async updateThemeSettings(theme) {
|
|
1141
|
-
await this.initializationPromise;
|
|
1142
|
-
await this.applyThemeSettings(theme);
|
|
951
|
+
class AreamapChartComponent {
|
|
952
|
+
constructor() {
|
|
953
|
+
/**
|
|
954
|
+
* {@inheritDoc @sisense/sdk-ui!AreamapChartProps.onDataPointClick}
|
|
955
|
+
*
|
|
956
|
+
* @category Callbacks
|
|
957
|
+
*/
|
|
958
|
+
this.dataPointClick = new EventEmitter();
|
|
959
|
+
/** @internal */
|
|
960
|
+
this.chartType = 'areamap';
|
|
1143
961
|
}
|
|
1144
|
-
}
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
]
|
|
1150
|
-
|
|
1151
|
-
|
|
962
|
+
}
|
|
963
|
+
AreamapChartComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: AreamapChartComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
964
|
+
AreamapChartComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: AreamapChartComponent, selector: "csdk-areamap-chart", inputs: { dataSet: "dataSet", dataOptions: "dataOptions", filters: "filters", highlights: "highlights", styleOptions: "styleOptions", dataReady: "dataReady" }, outputs: { dataPointClick: "dataPointClick" }, ngImport: i0, template: `
|
|
965
|
+
<csdk-chart
|
|
966
|
+
[chartType]="chartType"
|
|
967
|
+
[dataSet]="dataSet"
|
|
968
|
+
[dataOptions]="dataOptions"
|
|
969
|
+
[filters]="filters"
|
|
970
|
+
[highlights]="highlights"
|
|
971
|
+
[styleOptions]="styleOptions"
|
|
972
|
+
[dataReady]="dataReady"
|
|
973
|
+
(dataPointClick)="dataPointClick.emit($any($event))"
|
|
974
|
+
/>
|
|
975
|
+
`, isInline: true, dependencies: [{ kind: "component", type: ChartComponent, selector: "csdk-chart", inputs: ["chartType", "dataSet", "dataOptions", "filters", "highlights", "styleOptions", "beforeRender", "dataReady"], outputs: ["dataPointClick", "dataPointContextMenu", "dataPointsSelect"] }] });
|
|
976
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: AreamapChartComponent, decorators: [{
|
|
977
|
+
type: Component,
|
|
1152
978
|
args: [{
|
|
1153
|
-
|
|
979
|
+
selector: 'csdk-areamap-chart',
|
|
980
|
+
template: `
|
|
981
|
+
<csdk-chart
|
|
982
|
+
[chartType]="chartType"
|
|
983
|
+
[dataSet]="dataSet"
|
|
984
|
+
[dataOptions]="dataOptions"
|
|
985
|
+
[filters]="filters"
|
|
986
|
+
[highlights]="highlights"
|
|
987
|
+
[styleOptions]="styleOptions"
|
|
988
|
+
[dataReady]="dataReady"
|
|
989
|
+
(dataPointClick)="dataPointClick.emit($any($event))"
|
|
990
|
+
/>
|
|
991
|
+
`,
|
|
1154
992
|
}]
|
|
1155
|
-
}],
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
993
|
+
}], propDecorators: { dataSet: [{
|
|
994
|
+
type: Input
|
|
995
|
+
}], dataOptions: [{
|
|
996
|
+
type: Input
|
|
997
|
+
}], filters: [{
|
|
998
|
+
type: Input
|
|
999
|
+
}], highlights: [{
|
|
1000
|
+
type: Input
|
|
1001
|
+
}], styleOptions: [{
|
|
1002
|
+
type: Input
|
|
1003
|
+
}], dataReady: [{
|
|
1004
|
+
type: Input
|
|
1005
|
+
}], dataPointClick: [{
|
|
1006
|
+
type: Output
|
|
1007
|
+
}] } });
|
|
1161
1008
|
|
|
1162
1009
|
/**
|
|
1163
|
-
*
|
|
1010
|
+
* A component representing categorical data with horizontal rectangular bars,
|
|
1011
|
+
* whose lengths are proportional to the values that they represent.
|
|
1164
1012
|
*
|
|
1165
1013
|
* @example
|
|
1166
|
-
* An example of using the `Chart` component to
|
|
1167
|
-
* plot a column chart of the Sample Healthcare data source hosted in a Sisense instance:
|
|
1168
|
-
*
|
|
1169
1014
|
* ```html
|
|
1170
|
-
*
|
|
1171
|
-
*
|
|
1172
|
-
*
|
|
1173
|
-
*
|
|
1174
|
-
*
|
|
1175
|
-
*
|
|
1176
|
-
*
|
|
1177
|
-
*
|
|
1015
|
+
* <csdk-bar-chart
|
|
1016
|
+
* [dataSet]="chart.dataSet"
|
|
1017
|
+
* [dataOptions]="chart.dataOptions"
|
|
1018
|
+
* [highlights]="filters"
|
|
1019
|
+
* [beforeRender]="onBeforeRender"
|
|
1020
|
+
* (dataPointClick)="logArguments($event)"
|
|
1021
|
+
* (dataPointContextMenu)="logArguments($event)"
|
|
1022
|
+
* (dataPointsSelect)="logArguments($event)"
|
|
1023
|
+
* />
|
|
1178
1024
|
* ```
|
|
1179
1025
|
*
|
|
1180
1026
|
* ```ts
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
*
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1027
|
+
import { Component } from '@angular/core';
|
|
1028
|
+
import { measureFactory, filterFactory } from '@sisense/sdk-data';
|
|
1029
|
+
import * as DM from '../../assets/sample-healthcare-model';
|
|
1030
|
+
import type { ChartType } from '@sisense/sdk-ui-angular';
|
|
1031
|
+
|
|
1032
|
+
@Component({
|
|
1033
|
+
selector: 'app-analytics',
|
|
1034
|
+
templateUrl: './analytics.component.html',
|
|
1035
|
+
styleUrls: ['./analytics.component.scss'],
|
|
1036
|
+
})
|
|
1037
|
+
export class AnalyticsComponent {
|
|
1038
|
+
DM = DM;
|
|
1039
|
+
filters = [filterFactory.members(DM.Divisions.Divison_name, ['Cardiology', 'Neurology'])];
|
|
1040
|
+
chart = {
|
|
1041
|
+
chartType: 'column' as ChartType,
|
|
1042
|
+
dataSet: DM.DataSource,
|
|
1043
|
+
dataOptions: {
|
|
1044
|
+
category: [DM.Divisions.Divison_name],
|
|
1045
|
+
value: [measureFactory.sum(DM.Admissions.Cost_of_admission)],
|
|
1046
|
+
breakBy: [],
|
|
1047
|
+
},
|
|
1048
|
+
};
|
|
1049
|
+
|
|
1050
|
+
onBeforeRender(options: any) {
|
|
1051
|
+
console.log('beforeRender');
|
|
1052
|
+
console.log(options);
|
|
1053
|
+
return options;
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
logArguments(...args: any[]) {
|
|
1057
|
+
console.log(args);
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1208
1060
|
* ```
|
|
1209
|
-
*
|
|
1210
|
-
* <img src="media://angular-chart-example.png" width="800px" />
|
|
1211
|
-
* @shortDescription Common component for rendering charts of different types including table
|
|
1061
|
+
* <img src="media://angular-bar-chart-example.png" width="800px" />
|
|
1212
1062
|
* @group Charts
|
|
1213
1063
|
*/
|
|
1214
|
-
class
|
|
1215
|
-
|
|
1216
|
-
* Constructor for the `Chart` component.
|
|
1217
|
-
*
|
|
1218
|
-
* @param sisenseContextService - Sisense context service
|
|
1219
|
-
* @param themeService - Theme service
|
|
1220
|
-
*/
|
|
1221
|
-
constructor(
|
|
1222
|
-
/**
|
|
1223
|
-
* Sisense context service
|
|
1224
|
-
*
|
|
1225
|
-
* @category Constructor
|
|
1226
|
-
*/
|
|
1227
|
-
sisenseContextService,
|
|
1228
|
-
/**
|
|
1229
|
-
* Theme service
|
|
1230
|
-
*
|
|
1231
|
-
* @category Constructor
|
|
1232
|
-
*/
|
|
1233
|
-
themeService) {
|
|
1234
|
-
this.sisenseContextService = sisenseContextService;
|
|
1235
|
-
this.themeService = themeService;
|
|
1064
|
+
class BarChartComponent {
|
|
1065
|
+
constructor() {
|
|
1236
1066
|
/**
|
|
1237
|
-
* {@inheritDoc @sisense/sdk-ui!
|
|
1067
|
+
* {@inheritDoc @sisense/sdk-ui!BarChartProps.onDataPointClick}
|
|
1238
1068
|
*
|
|
1239
1069
|
* @category Callbacks
|
|
1240
1070
|
*/
|
|
1241
1071
|
this.dataPointClick = new EventEmitter();
|
|
1242
1072
|
/**
|
|
1243
|
-
* {@inheritDoc @sisense/sdk-ui!
|
|
1073
|
+
* {@inheritDoc @sisense/sdk-ui!BarChartProps.onDataPointContextMenu}
|
|
1244
1074
|
*
|
|
1245
1075
|
* @category Callbacks
|
|
1246
1076
|
*/
|
|
1247
1077
|
this.dataPointContextMenu = new EventEmitter();
|
|
1248
1078
|
/**
|
|
1249
|
-
* {@inheritDoc @sisense/sdk-ui!
|
|
1079
|
+
* {@inheritDoc @sisense/sdk-ui!BarChartProps.onDataPointsSelected}
|
|
1250
1080
|
*
|
|
1251
1081
|
* @category Callbacks
|
|
1252
1082
|
*/
|
|
1253
1083
|
this.dataPointsSelect = new EventEmitter();
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
createThemeContextConnector(this.themeService),
|
|
1257
|
-
]);
|
|
1258
|
-
}
|
|
1259
|
-
/**
|
|
1260
|
-
* @internal
|
|
1261
|
-
*/
|
|
1262
|
-
ngAfterViewInit() {
|
|
1263
|
-
this.componentAdapter.render(this.preactRef.nativeElement, this.getPreactComponentProps());
|
|
1264
|
-
}
|
|
1265
|
-
/**
|
|
1266
|
-
* @internal
|
|
1267
|
-
*/
|
|
1268
|
-
ngOnChanges() {
|
|
1269
|
-
if (this.preactRef) {
|
|
1270
|
-
this.componentAdapter.render(this.preactRef.nativeElement, this.getPreactComponentProps());
|
|
1271
|
-
}
|
|
1272
|
-
}
|
|
1273
|
-
getPreactComponentProps() {
|
|
1274
|
-
return {
|
|
1275
|
-
chartType: this.chartType,
|
|
1276
|
-
dataSet: this.dataSet,
|
|
1277
|
-
dataOptions: this.dataOptions,
|
|
1278
|
-
filters: this.filters,
|
|
1279
|
-
highlights: this.highlights,
|
|
1280
|
-
styleOptions: this.styleOptions,
|
|
1281
|
-
onBeforeRender: this.beforeRender?.bind(this),
|
|
1282
|
-
onDataReady: this.dataReady?.bind(this),
|
|
1283
|
-
onDataPointClick: (...[point, nativeEvent]) => this.dataPointClick.emit({ point, nativeEvent }),
|
|
1284
|
-
onDataPointContextMenu: (...[point, nativeEvent]) => this.dataPointContextMenu.emit({ point, nativeEvent }),
|
|
1285
|
-
onDataPointsSelected: (...[points, nativeEvent]) => this.dataPointsSelect.emit({ points, nativeEvent }),
|
|
1286
|
-
};
|
|
1287
|
-
}
|
|
1288
|
-
/**
|
|
1289
|
-
* @internal
|
|
1290
|
-
*/
|
|
1291
|
-
ngOnDestroy() {
|
|
1292
|
-
this.componentAdapter.destroy();
|
|
1084
|
+
/** @internal */
|
|
1085
|
+
this.chartType = 'bar';
|
|
1293
1086
|
}
|
|
1294
1087
|
}
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1088
|
+
BarChartComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: BarChartComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1089
|
+
BarChartComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: BarChartComponent, selector: "csdk-bar-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: `
|
|
1090
|
+
<csdk-chart
|
|
1091
|
+
[chartType]="chartType"
|
|
1092
|
+
[dataSet]="dataSet"
|
|
1093
|
+
[dataOptions]="dataOptions"
|
|
1094
|
+
[filters]="filters"
|
|
1095
|
+
[highlights]="highlights"
|
|
1096
|
+
[styleOptions]="styleOptions"
|
|
1097
|
+
[beforeRender]="beforeRender"
|
|
1098
|
+
[dataReady]="dataReady"
|
|
1099
|
+
(dataPointClick)="dataPointClick.emit($any($event))"
|
|
1100
|
+
(dataPointContextMenu)="dataPointContextMenu.emit($any($event))"
|
|
1101
|
+
(dataPointsSelect)="dataPointsSelect.emit($any($event))"
|
|
1102
|
+
/>
|
|
1103
|
+
`, isInline: true, dependencies: [{ kind: "component", type: ChartComponent, selector: "csdk-chart", inputs: ["chartType", "dataSet", "dataOptions", "filters", "highlights", "styleOptions", "beforeRender", "dataReady"], outputs: ["dataPointClick", "dataPointContextMenu", "dataPointsSelect"] }] });
|
|
1104
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: BarChartComponent, decorators: [{
|
|
1298
1105
|
type: Component,
|
|
1299
|
-
args: [{
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1106
|
+
args: [{
|
|
1107
|
+
selector: 'csdk-bar-chart',
|
|
1108
|
+
template: `
|
|
1109
|
+
<csdk-chart
|
|
1110
|
+
[chartType]="chartType"
|
|
1111
|
+
[dataSet]="dataSet"
|
|
1112
|
+
[dataOptions]="dataOptions"
|
|
1113
|
+
[filters]="filters"
|
|
1114
|
+
[highlights]="highlights"
|
|
1115
|
+
[styleOptions]="styleOptions"
|
|
1116
|
+
[beforeRender]="beforeRender"
|
|
1117
|
+
[dataReady]="dataReady"
|
|
1118
|
+
(dataPointClick)="dataPointClick.emit($any($event))"
|
|
1119
|
+
(dataPointContextMenu)="dataPointContextMenu.emit($any($event))"
|
|
1120
|
+
(dataPointsSelect)="dataPointsSelect.emit($any($event))"
|
|
1121
|
+
/>
|
|
1122
|
+
`,
|
|
1123
|
+
}]
|
|
1124
|
+
}], propDecorators: { dataSet: [{
|
|
1306
1125
|
type: Input
|
|
1307
1126
|
}], dataOptions: [{
|
|
1308
1127
|
type: Input
|
|
@@ -1325,26 +1144,27 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
|
|
|
1325
1144
|
}] } });
|
|
1326
1145
|
|
|
1327
1146
|
/**
|
|
1328
|
-
*
|
|
1329
|
-
*
|
|
1147
|
+
* An Angular component representing data in a way that visually describes the distribution
|
|
1148
|
+
* variability, and center of a data set along an axis.
|
|
1330
1149
|
*
|
|
1331
1150
|
* @example
|
|
1332
1151
|
* ```html
|
|
1333
|
-
* <csdk-
|
|
1334
|
-
* [dataSet]="
|
|
1335
|
-
* [dataOptions]="
|
|
1336
|
-
* [highlights]="
|
|
1152
|
+
* <csdk-boxplot-chart
|
|
1153
|
+
* [dataSet]="boxplotChart.dataSet"
|
|
1154
|
+
* [dataOptions]="boxplotChart.dataOptions"
|
|
1155
|
+
* [highlights]="boxplotChart.highlights"
|
|
1337
1156
|
* [beforeRender]="onBeforeRender"
|
|
1338
1157
|
* (dataPointClick)="logArguments($event)"
|
|
1339
1158
|
* (dataPointContextMenu)="logArguments($event)"
|
|
1340
1159
|
* (dataPointsSelect)="logArguments($event)"
|
|
1341
1160
|
* />
|
|
1342
1161
|
* ```
|
|
1162
|
+
*
|
|
1343
1163
|
* ```ts
|
|
1344
1164
|
import { Component } from '@angular/core';
|
|
1345
|
-
import {
|
|
1165
|
+
import { filterFactory } from '@sisense/sdk-data';
|
|
1166
|
+
import type { BoxplotChartDataOptions } from '@sisense/sdk-ui-angular';
|
|
1346
1167
|
import * as DM from '../../assets/sample-healthcare-model';
|
|
1347
|
-
import type { ChartType } from '@sisense/sdk-ui-angular';
|
|
1348
1168
|
|
|
1349
1169
|
@Component({
|
|
1350
1170
|
selector: 'app-analytics',
|
|
@@ -1352,58 +1172,51 @@ import type { ChartType } from '@sisense/sdk-ui-angular';
|
|
|
1352
1172
|
styleUrls: ['./analytics.component.scss'],
|
|
1353
1173
|
})
|
|
1354
1174
|
export class AnalyticsComponent {
|
|
1355
|
-
|
|
1356
|
-
filters = [filterFactory.members(DM.Divisions.Divison_name, ['Cardiology', 'Neurology'])];
|
|
1357
|
-
chart = {
|
|
1358
|
-
chartType: 'column' as ChartType,
|
|
1175
|
+
boxplotChart = {
|
|
1359
1176
|
dataSet: DM.DataSource,
|
|
1360
1177
|
dataOptions: {
|
|
1361
1178
|
category: [DM.Divisions.Divison_name],
|
|
1362
|
-
value: [
|
|
1363
|
-
|
|
1364
|
-
|
|
1179
|
+
value: [DM.Admissions.TimeofStay],
|
|
1180
|
+
boxType: 'iqr',
|
|
1181
|
+
outliersEnabled: true,
|
|
1182
|
+
} as BoxplotChartDataOptions,
|
|
1183
|
+
highlights: [filterFactory.members(DM.Divisions.Divison_name, ['Cardiology', 'Neurology'])],
|
|
1365
1184
|
};
|
|
1366
1185
|
|
|
1367
|
-
onBeforeRender(options: any) {
|
|
1368
|
-
console.log('beforeRender');
|
|
1369
|
-
console.log(options);
|
|
1370
|
-
return options;
|
|
1371
|
-
}
|
|
1372
|
-
|
|
1373
1186
|
logArguments(...args: any[]) {
|
|
1374
1187
|
console.log(args);
|
|
1375
1188
|
}
|
|
1376
1189
|
}
|
|
1377
1190
|
* ```
|
|
1378
|
-
* <img src="media://angular-
|
|
1191
|
+
* <img src="media://angular-boxplot-chart-example.png" width="800px" />
|
|
1379
1192
|
* @group Charts
|
|
1380
1193
|
*/
|
|
1381
|
-
class
|
|
1194
|
+
class BoxplotChartComponent {
|
|
1382
1195
|
constructor() {
|
|
1383
1196
|
/**
|
|
1384
|
-
* {@inheritDoc @sisense/sdk-ui!
|
|
1197
|
+
* {@inheritDoc @sisense/sdk-ui!BoxplotChartProps.onDataPointClick}
|
|
1385
1198
|
*
|
|
1386
1199
|
* @category Callbacks
|
|
1387
1200
|
*/
|
|
1388
1201
|
this.dataPointClick = new EventEmitter();
|
|
1389
1202
|
/**
|
|
1390
|
-
* {@inheritDoc @sisense/sdk-ui!
|
|
1203
|
+
* {@inheritDoc @sisense/sdk-ui!BoxplotChartProps.onDataPointContextMenu}
|
|
1391
1204
|
*
|
|
1392
1205
|
* @category Callbacks
|
|
1393
1206
|
*/
|
|
1394
1207
|
this.dataPointContextMenu = new EventEmitter();
|
|
1395
1208
|
/**
|
|
1396
|
-
* {@inheritDoc @sisense/sdk-ui!
|
|
1209
|
+
* {@inheritDoc @sisense/sdk-ui!BoxplotChartProps.onDataPointsSelected}
|
|
1397
1210
|
*
|
|
1398
1211
|
* @category Callbacks
|
|
1399
1212
|
*/
|
|
1400
1213
|
this.dataPointsSelect = new EventEmitter();
|
|
1401
1214
|
/** @internal */
|
|
1402
|
-
this.chartType = '
|
|
1215
|
+
this.chartType = 'boxplot';
|
|
1403
1216
|
}
|
|
1404
1217
|
}
|
|
1405
|
-
|
|
1406
|
-
|
|
1218
|
+
BoxplotChartComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: BoxplotChartComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1219
|
+
BoxplotChartComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: BoxplotChartComponent, selector: "csdk-boxplot-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: `
|
|
1407
1220
|
<csdk-chart
|
|
1408
1221
|
[chartType]="chartType"
|
|
1409
1222
|
[dataSet]="dataSet"
|
|
@@ -1418,10 +1231,10 @@ AreaChartComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", ver
|
|
|
1418
1231
|
(dataPointsSelect)="dataPointsSelect.emit($any($event))"
|
|
1419
1232
|
/>
|
|
1420
1233
|
`, isInline: true, dependencies: [{ kind: "component", type: ChartComponent, selector: "csdk-chart", inputs: ["chartType", "dataSet", "dataOptions", "filters", "highlights", "styleOptions", "beforeRender", "dataReady"], outputs: ["dataPointClick", "dataPointContextMenu", "dataPointsSelect"] }] });
|
|
1421
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type:
|
|
1234
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: BoxplotChartComponent, decorators: [{
|
|
1422
1235
|
type: Component,
|
|
1423
1236
|
args: [{
|
|
1424
|
-
selector: 'csdk-
|
|
1237
|
+
selector: 'csdk-boxplot-chart',
|
|
1425
1238
|
template: `
|
|
1426
1239
|
<csdk-chart
|
|
1427
1240
|
[chartType]="chartType"
|
|
@@ -1461,27 +1274,23 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
|
|
|
1461
1274
|
}] } });
|
|
1462
1275
|
|
|
1463
1276
|
/**
|
|
1464
|
-
* A component that
|
|
1465
|
-
*
|
|
1466
|
-
* the area between these values.
|
|
1277
|
+
* A component that visualizes values over days in a calendar-like view,
|
|
1278
|
+
* making it easy to identify daily patterns or anomalies
|
|
1467
1279
|
*
|
|
1468
1280
|
* @example
|
|
1469
1281
|
* ```html
|
|
1470
|
-
* <csdk-
|
|
1282
|
+
* <csdk-calendar-heatmap-chart
|
|
1471
1283
|
* [dataSet]="chart.dataSet"
|
|
1472
1284
|
* [dataOptions]="chart.dataOptions"
|
|
1473
|
-
* [highlights]="
|
|
1474
|
-
* [
|
|
1475
|
-
* (dataPointClick)="logArguments($event)"
|
|
1476
|
-
* (dataPointContextMenu)="logArguments($event)"
|
|
1477
|
-
* (dataPointsSelect)="logArguments($event)"
|
|
1285
|
+
* [highlights]="chart.highlights"
|
|
1286
|
+
* [styleOptions]="chart.styleOptions"
|
|
1478
1287
|
* />
|
|
1479
1288
|
* ```
|
|
1480
|
-
* ```ts
|
|
1481
|
-
import { Component } from '@angular/core';
|
|
1482
|
-
import { measureFactory, filterFactory
|
|
1483
|
-
import * as DM from '../../assets/sample-
|
|
1484
|
-
import type {
|
|
1289
|
+
* ```ts
|
|
1290
|
+
import { Component } from '@angular/core';
|
|
1291
|
+
import { measureFactory, filterFactory } from '@sisense/sdk-data';
|
|
1292
|
+
import * as DM from '../../assets/sample-ecommerce';
|
|
1293
|
+
import type { CalendarHeatmapChartProps } from '@sisense/sdk-ui-angular';
|
|
1485
1294
|
|
|
1486
1295
|
@Component({
|
|
1487
1296
|
selector: 'app-analytics',
|
|
@@ -1490,69 +1299,54 @@ import type { ChartType, RangeChartDataOptions } from '@sisense/sdk-ui-angular';
|
|
|
1490
1299
|
})
|
|
1491
1300
|
export class AnalyticsComponent {
|
|
1492
1301
|
DM = DM;
|
|
1493
|
-
filters = [filterFactory.members(DM.Divisions.Divison_name, ['Cardiology', 'Neurology'])];
|
|
1494
1302
|
chart = {
|
|
1495
|
-
chartType: 'arearange' as ChartType,
|
|
1496
1303
|
dataSet: DM.DataSource,
|
|
1497
1304
|
dataOptions: {
|
|
1498
|
-
|
|
1499
|
-
value:
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
],
|
|
1512
|
-
breakBy: [],
|
|
1513
|
-
} as RangeChartDataOptions,
|
|
1305
|
+
date: DM.Commerce.Date.Days,
|
|
1306
|
+
value: measureFactory.sum(DM.Commerce.Cost),
|
|
1307
|
+
},
|
|
1308
|
+
highlights: [
|
|
1309
|
+
filterFactory.dateRange(
|
|
1310
|
+
DM.Commerce.Date.Days,
|
|
1311
|
+
'2009-11-29',
|
|
1312
|
+
'2009-12-15'
|
|
1313
|
+
),
|
|
1314
|
+
],
|
|
1315
|
+
styleOptions: {
|
|
1316
|
+
viewType: 'quarter',
|
|
1317
|
+
},
|
|
1514
1318
|
};
|
|
1515
|
-
|
|
1516
|
-
onBeforeRender(options: any) {
|
|
1517
|
-
console.log('beforeRender');
|
|
1518
|
-
console.log(options);
|
|
1519
|
-
return options;
|
|
1520
|
-
}
|
|
1521
|
-
|
|
1522
|
-
logArguments(...args: any[]) {
|
|
1523
|
-
console.log(args);
|
|
1524
|
-
}
|
|
1525
1319
|
}
|
|
1526
1320
|
* ```
|
|
1527
|
-
* <img src="media://angular-
|
|
1321
|
+
* <img src="media://angular-calendar-heatmap-chart-example.png" width="800px" />
|
|
1528
1322
|
* @group Charts
|
|
1529
1323
|
*/
|
|
1530
|
-
class
|
|
1324
|
+
class CalendarHeatmapChartComponent {
|
|
1531
1325
|
constructor() {
|
|
1532
1326
|
/**
|
|
1533
|
-
* {@inheritDoc @sisense/sdk-ui!
|
|
1327
|
+
* {@inheritDoc @sisense/sdk-ui!CalendarHeatmapChartProps.onDataPointClick}
|
|
1534
1328
|
*
|
|
1535
1329
|
* @category Callbacks
|
|
1536
1330
|
*/
|
|
1537
1331
|
this.dataPointClick = new EventEmitter();
|
|
1538
1332
|
/**
|
|
1539
|
-
* {@inheritDoc @sisense/sdk-ui!
|
|
1333
|
+
* {@inheritDoc @sisense/sdk-ui!CalendarHeatmapChartProps.onDataPointContextMenu}
|
|
1540
1334
|
*
|
|
1541
1335
|
* @category Callbacks
|
|
1542
1336
|
*/
|
|
1543
1337
|
this.dataPointContextMenu = new EventEmitter();
|
|
1544
1338
|
/**
|
|
1545
|
-
* {@inheritDoc @sisense/sdk-ui!
|
|
1339
|
+
* {@inheritDoc @sisense/sdk-ui!CalendarHeatmapChartProps.onDataPointsSelected}
|
|
1546
1340
|
*
|
|
1547
1341
|
* @category Callbacks
|
|
1548
1342
|
*/
|
|
1549
1343
|
this.dataPointsSelect = new EventEmitter();
|
|
1550
1344
|
/** @internal */
|
|
1551
|
-
this.chartType = '
|
|
1345
|
+
this.chartType = 'calendar-heatmap';
|
|
1552
1346
|
}
|
|
1553
1347
|
}
|
|
1554
|
-
|
|
1555
|
-
|
|
1348
|
+
CalendarHeatmapChartComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: CalendarHeatmapChartComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1349
|
+
CalendarHeatmapChartComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: CalendarHeatmapChartComponent, selector: "csdk-calendar-heatmap-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: `
|
|
1556
1350
|
<csdk-chart
|
|
1557
1351
|
[chartType]="chartType"
|
|
1558
1352
|
[dataSet]="dataSet"
|
|
@@ -1567,10 +1361,10 @@ AreaRangeChartComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0"
|
|
|
1567
1361
|
(dataPointsSelect)="dataPointsSelect.emit($any($event))"
|
|
1568
1362
|
/>
|
|
1569
1363
|
`, isInline: true, dependencies: [{ kind: "component", type: ChartComponent, selector: "csdk-chart", inputs: ["chartType", "dataSet", "dataOptions", "filters", "highlights", "styleOptions", "beforeRender", "dataReady"], outputs: ["dataPointClick", "dataPointContextMenu", "dataPointsSelect"] }] });
|
|
1570
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type:
|
|
1364
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: CalendarHeatmapChartComponent, decorators: [{
|
|
1571
1365
|
type: Component,
|
|
1572
1366
|
args: [{
|
|
1573
|
-
selector: 'csdk-
|
|
1367
|
+
selector: 'csdk-calendar-heatmap-chart',
|
|
1574
1368
|
template: `
|
|
1575
1369
|
<csdk-chart
|
|
1576
1370
|
[chartType]="chartType"
|
|
@@ -1610,22 +1404,26 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
|
|
|
1610
1404
|
}] } });
|
|
1611
1405
|
|
|
1612
1406
|
/**
|
|
1613
|
-
*
|
|
1407
|
+
* A component representing categorical data with vertical rectangular bars
|
|
1408
|
+
* whose heights are proportional to the values that they represent.
|
|
1614
1409
|
*
|
|
1615
1410
|
* @example
|
|
1616
1411
|
* ```html
|
|
1617
|
-
* <csdk-
|
|
1618
|
-
* [dataSet]="
|
|
1619
|
-
* [dataOptions]="
|
|
1620
|
-
* [
|
|
1412
|
+
* <csdk-column-chart
|
|
1413
|
+
* [dataSet]="chart.dataSet"
|
|
1414
|
+
* [dataOptions]="chart.dataOptions"
|
|
1415
|
+
* [highlights]="filters"
|
|
1416
|
+
* [beforeRender]="onBeforeRender"
|
|
1621
1417
|
* (dataPointClick)="logArguments($event)"
|
|
1418
|
+
* (dataPointContextMenu)="logArguments($event)"
|
|
1419
|
+
* (dataPointsSelect)="logArguments($event)"
|
|
1622
1420
|
* />
|
|
1623
1421
|
* ```
|
|
1624
|
-
*
|
|
1625
1422
|
* ```ts
|
|
1626
1423
|
import { Component } from '@angular/core';
|
|
1627
|
-
import { measureFactory } from '@sisense/sdk-data';
|
|
1628
|
-
import * as DM from '../../assets/sample-
|
|
1424
|
+
import { measureFactory, filterFactory } from '@sisense/sdk-data';
|
|
1425
|
+
import * as DM from '../../assets/sample-healthcare-model';
|
|
1426
|
+
import type { ChartType } from '@sisense/sdk-ui-angular';
|
|
1629
1427
|
|
|
1630
1428
|
@Component({
|
|
1631
1429
|
selector: 'app-analytics',
|
|
@@ -1633,39 +1431,58 @@ import * as DM from '../../assets/sample-ecommerce';
|
|
|
1633
1431
|
styleUrls: ['./analytics.component.scss'],
|
|
1634
1432
|
})
|
|
1635
1433
|
export class AnalyticsComponent {
|
|
1636
|
-
|
|
1434
|
+
DM = DM;
|
|
1435
|
+
filters = [filterFactory.members(DM.Divisions.Divison_name, ['Cardiology', 'Neurology'])];
|
|
1436
|
+
chart = {
|
|
1437
|
+
chartType: 'column' as ChartType,
|
|
1637
1438
|
dataSet: DM.DataSource,
|
|
1638
1439
|
dataOptions: {
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
mapType: 'world',
|
|
1644
|
-
} as AreamapStyleOptions,
|
|
1440
|
+
category: [DM.Divisions.Divison_name],
|
|
1441
|
+
value: [measureFactory.sum(DM.Admissions.Cost_of_admission)],
|
|
1442
|
+
breakBy: [],
|
|
1443
|
+
},
|
|
1645
1444
|
};
|
|
1646
1445
|
|
|
1446
|
+
onBeforeRender(options: any) {
|
|
1447
|
+
console.log('beforeRender');
|
|
1448
|
+
console.log(options);
|
|
1449
|
+
return options;
|
|
1450
|
+
}
|
|
1451
|
+
|
|
1647
1452
|
logArguments(...args: any[]) {
|
|
1648
1453
|
console.log(args);
|
|
1649
1454
|
}
|
|
1650
1455
|
}
|
|
1651
1456
|
* ```
|
|
1652
|
-
* <img src="media://angular-
|
|
1457
|
+
* <img src="media://angular-column-chart-example.png" width="800px" />
|
|
1653
1458
|
* @group Charts
|
|
1654
1459
|
*/
|
|
1655
|
-
class
|
|
1460
|
+
class ColumnChartComponent {
|
|
1656
1461
|
constructor() {
|
|
1657
1462
|
/**
|
|
1658
|
-
* {@inheritDoc @sisense/sdk-ui!
|
|
1463
|
+
* {@inheritDoc @sisense/sdk-ui!ColumnChartProps.onDataPointClick}
|
|
1659
1464
|
*
|
|
1660
1465
|
* @category Callbacks
|
|
1661
1466
|
*/
|
|
1662
1467
|
this.dataPointClick = new EventEmitter();
|
|
1468
|
+
/**
|
|
1469
|
+
* {@inheritDoc @sisense/sdk-ui!ColumnChartProps.onDataPointContextMenu}
|
|
1470
|
+
*
|
|
1471
|
+
* @category Callbacks
|
|
1472
|
+
*/
|
|
1473
|
+
this.dataPointContextMenu = new EventEmitter();
|
|
1474
|
+
/**
|
|
1475
|
+
* {@inheritDoc @sisense/sdk-ui!ColumnChartProps.onDataPointsSelected}
|
|
1476
|
+
*
|
|
1477
|
+
* @category Callbacks
|
|
1478
|
+
*/
|
|
1479
|
+
this.dataPointsSelect = new EventEmitter();
|
|
1663
1480
|
/** @internal */
|
|
1664
|
-
this.chartType = '
|
|
1481
|
+
this.chartType = 'column';
|
|
1665
1482
|
}
|
|
1666
1483
|
}
|
|
1667
|
-
|
|
1668
|
-
|
|
1484
|
+
ColumnChartComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: ColumnChartComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1485
|
+
ColumnChartComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: ColumnChartComponent, selector: "csdk-column-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: `
|
|
1669
1486
|
<csdk-chart
|
|
1670
1487
|
[chartType]="chartType"
|
|
1671
1488
|
[dataSet]="dataSet"
|
|
@@ -1673,14 +1490,17 @@ AreamapChartComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0",
|
|
|
1673
1490
|
[filters]="filters"
|
|
1674
1491
|
[highlights]="highlights"
|
|
1675
1492
|
[styleOptions]="styleOptions"
|
|
1493
|
+
[beforeRender]="beforeRender"
|
|
1676
1494
|
[dataReady]="dataReady"
|
|
1677
1495
|
(dataPointClick)="dataPointClick.emit($any($event))"
|
|
1496
|
+
(dataPointContextMenu)="dataPointContextMenu.emit($any($event))"
|
|
1497
|
+
(dataPointsSelect)="dataPointsSelect.emit($any($event))"
|
|
1678
1498
|
/>
|
|
1679
1499
|
`, isInline: true, dependencies: [{ kind: "component", type: ChartComponent, selector: "csdk-chart", inputs: ["chartType", "dataSet", "dataOptions", "filters", "highlights", "styleOptions", "beforeRender", "dataReady"], outputs: ["dataPointClick", "dataPointContextMenu", "dataPointsSelect"] }] });
|
|
1680
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type:
|
|
1500
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: ColumnChartComponent, decorators: [{
|
|
1681
1501
|
type: Component,
|
|
1682
1502
|
args: [{
|
|
1683
|
-
selector: 'csdk-
|
|
1503
|
+
selector: 'csdk-column-chart',
|
|
1684
1504
|
template: `
|
|
1685
1505
|
<csdk-chart
|
|
1686
1506
|
[chartType]="chartType"
|
|
@@ -1689,8 +1509,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
|
|
|
1689
1509
|
[filters]="filters"
|
|
1690
1510
|
[highlights]="highlights"
|
|
1691
1511
|
[styleOptions]="styleOptions"
|
|
1512
|
+
[beforeRender]="beforeRender"
|
|
1692
1513
|
[dataReady]="dataReady"
|
|
1693
1514
|
(dataPointClick)="dataPointClick.emit($any($event))"
|
|
1515
|
+
(dataPointContextMenu)="dataPointContextMenu.emit($any($event))"
|
|
1516
|
+
(dataPointsSelect)="dataPointsSelect.emit($any($event))"
|
|
1694
1517
|
/>
|
|
1695
1518
|
`,
|
|
1696
1519
|
}]
|
|
@@ -1704,19 +1527,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
|
|
|
1704
1527
|
type: Input
|
|
1705
1528
|
}], styleOptions: [{
|
|
1706
1529
|
type: Input
|
|
1530
|
+
}], beforeRender: [{
|
|
1531
|
+
type: Input
|
|
1707
1532
|
}], dataReady: [{
|
|
1708
1533
|
type: Input
|
|
1709
1534
|
}], dataPointClick: [{
|
|
1710
1535
|
type: Output
|
|
1536
|
+
}], dataPointContextMenu: [{
|
|
1537
|
+
type: Output
|
|
1538
|
+
}], dataPointsSelect: [{
|
|
1539
|
+
type: Output
|
|
1711
1540
|
}] } });
|
|
1712
1541
|
|
|
1713
1542
|
/**
|
|
1714
|
-
* A component representing
|
|
1715
|
-
* whose lengths are proportional to the values that they represent.
|
|
1543
|
+
* A component representing data progressively decreasing in size or quantity through a funnel shape.
|
|
1716
1544
|
*
|
|
1717
1545
|
* @example
|
|
1718
1546
|
* ```html
|
|
1719
|
-
* <csdk-
|
|
1547
|
+
* <csdk-funnel-chart
|
|
1720
1548
|
* [dataSet]="chart.dataSet"
|
|
1721
1549
|
* [dataOptions]="chart.dataOptions"
|
|
1722
1550
|
* [highlights]="filters"
|
|
@@ -1726,13 +1554,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
|
|
|
1726
1554
|
* (dataPointsSelect)="logArguments($event)"
|
|
1727
1555
|
* />
|
|
1728
1556
|
* ```
|
|
1729
|
-
*
|
|
1730
1557
|
* ```ts
|
|
1731
1558
|
import { Component } from '@angular/core';
|
|
1732
|
-
import { measureFactory, filterFactory } from '@sisense/sdk-data';
|
|
1559
|
+
import { measureFactory, filterFactory, Filter } from '@sisense/sdk-data';
|
|
1733
1560
|
import * as DM from '../../assets/sample-healthcare-model';
|
|
1734
1561
|
import type { ChartType } from '@sisense/sdk-ui-angular';
|
|
1735
|
-
|
|
1736
1562
|
@Component({
|
|
1737
1563
|
selector: 'app-analytics',
|
|
1738
1564
|
templateUrl: './analytics.component.html',
|
|
@@ -1762,35 +1588,35 @@ export class AnalyticsComponent {
|
|
|
1762
1588
|
}
|
|
1763
1589
|
}
|
|
1764
1590
|
* ```
|
|
1765
|
-
* <img src="media://angular-
|
|
1591
|
+
* <img src="media://angular-funnel-chart-example.png" width="800px" />
|
|
1766
1592
|
* @group Charts
|
|
1767
1593
|
*/
|
|
1768
|
-
class
|
|
1594
|
+
class FunnelChartComponent {
|
|
1769
1595
|
constructor() {
|
|
1770
1596
|
/**
|
|
1771
|
-
* {@inheritDoc @sisense/sdk-ui!
|
|
1597
|
+
* {@inheritDoc @sisense/sdk-ui!FunnelChartProps.onDataPointClick}
|
|
1772
1598
|
*
|
|
1773
1599
|
* @category Callbacks
|
|
1774
1600
|
*/
|
|
1775
1601
|
this.dataPointClick = new EventEmitter();
|
|
1776
1602
|
/**
|
|
1777
|
-
* {@inheritDoc @sisense/sdk-ui!
|
|
1603
|
+
* {@inheritDoc @sisense/sdk-ui!FunnelChartProps.onDataPointContextMenu}
|
|
1778
1604
|
*
|
|
1779
1605
|
* @category Callbacks
|
|
1780
1606
|
*/
|
|
1781
1607
|
this.dataPointContextMenu = new EventEmitter();
|
|
1782
1608
|
/**
|
|
1783
|
-
* {@inheritDoc @sisense/sdk-ui!
|
|
1609
|
+
* {@inheritDoc @sisense/sdk-ui!FunnelChartProps.onDataPointsSelected}
|
|
1784
1610
|
*
|
|
1785
1611
|
* @category Callbacks
|
|
1786
1612
|
*/
|
|
1787
1613
|
this.dataPointsSelect = new EventEmitter();
|
|
1788
1614
|
/** @internal */
|
|
1789
|
-
this.chartType = '
|
|
1615
|
+
this.chartType = 'funnel';
|
|
1790
1616
|
}
|
|
1791
1617
|
}
|
|
1792
|
-
|
|
1793
|
-
|
|
1618
|
+
FunnelChartComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: FunnelChartComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1619
|
+
FunnelChartComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: FunnelChartComponent, selector: "csdk-funnel-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: `
|
|
1794
1620
|
<csdk-chart
|
|
1795
1621
|
[chartType]="chartType"
|
|
1796
1622
|
[dataSet]="dataSet"
|
|
@@ -1805,10 +1631,10 @@ BarChartComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", vers
|
|
|
1805
1631
|
(dataPointsSelect)="dataPointsSelect.emit($any($event))"
|
|
1806
1632
|
/>
|
|
1807
1633
|
`, isInline: true, dependencies: [{ kind: "component", type: ChartComponent, selector: "csdk-chart", inputs: ["chartType", "dataSet", "dataOptions", "filters", "highlights", "styleOptions", "beforeRender", "dataReady"], outputs: ["dataPointClick", "dataPointContextMenu", "dataPointsSelect"] }] });
|
|
1808
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type:
|
|
1634
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: FunnelChartComponent, decorators: [{
|
|
1809
1635
|
type: Component,
|
|
1810
1636
|
args: [{
|
|
1811
|
-
selector: 'csdk-
|
|
1637
|
+
selector: 'csdk-funnel-chart',
|
|
1812
1638
|
template: `
|
|
1813
1639
|
<csdk-chart
|
|
1814
1640
|
[chartType]="chartType"
|
|
@@ -1848,27 +1674,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
|
|
|
1848
1674
|
}] } });
|
|
1849
1675
|
|
|
1850
1676
|
/**
|
|
1851
|
-
*
|
|
1852
|
-
* variability, and center of a data set along an axis.
|
|
1677
|
+
* A component that provides various options for displaying one or two numeric values as a number, gauge or ticker.
|
|
1853
1678
|
*
|
|
1854
1679
|
* @example
|
|
1855
1680
|
* ```html
|
|
1856
|
-
* <csdk-
|
|
1857
|
-
* [dataSet]="
|
|
1858
|
-
* [dataOptions]="
|
|
1859
|
-
* [
|
|
1860
|
-
* [
|
|
1861
|
-
* (dataPointClick)="logArguments($event)"
|
|
1862
|
-
* (dataPointContextMenu)="logArguments($event)"
|
|
1863
|
-
* (dataPointsSelect)="logArguments($event)"
|
|
1681
|
+
* <csdk-indicator-chart
|
|
1682
|
+
* [dataSet]="indicator.dataSet"
|
|
1683
|
+
* [dataOptions]="indicator.dataOptions"
|
|
1684
|
+
* [filters]="filters"
|
|
1685
|
+
* [styleOptions]="indicator.styleOptions"
|
|
1864
1686
|
* />
|
|
1865
1687
|
* ```
|
|
1866
|
-
*
|
|
1867
1688
|
* ```ts
|
|
1868
1689
|
import { Component } from '@angular/core';
|
|
1869
|
-
import { filterFactory } from '@sisense/sdk-data';
|
|
1870
|
-
import type { BoxplotChartDataOptions } from '@sisense/sdk-ui-angular';
|
|
1690
|
+
import { measureFactory, filterFactory } from '@sisense/sdk-data';
|
|
1871
1691
|
import * as DM from '../../assets/sample-healthcare-model';
|
|
1692
|
+
import type { IndicatorStyleOptions } from '@sisense/sdk-ui-angular';
|
|
1872
1693
|
|
|
1873
1694
|
@Component({
|
|
1874
1695
|
selector: 'app-analytics',
|
|
@@ -1876,51 +1697,48 @@ import * as DM from '../../assets/sample-healthcare-model';
|
|
|
1876
1697
|
styleUrls: ['./analytics.component.scss'],
|
|
1877
1698
|
})
|
|
1878
1699
|
export class AnalyticsComponent {
|
|
1879
|
-
|
|
1700
|
+
DM = DM;
|
|
1701
|
+
filters = [filterFactory.members(DM.Divisions.Divison_name, ['Cardiology', 'Neurology'])];
|
|
1702
|
+
indicator = {
|
|
1880
1703
|
dataSet: DM.DataSource,
|
|
1881
1704
|
dataOptions: {
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
}
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
* {@inheritDoc @sisense/sdk-ui!BoxplotChartProps.onDataPointsSelected}
|
|
1914
|
-
*
|
|
1915
|
-
* @category Callbacks
|
|
1916
|
-
*/
|
|
1917
|
-
this.dataPointsSelect = new EventEmitter();
|
|
1705
|
+
value: [measureFactory.sum(DM.Admissions.Cost_of_admission)],
|
|
1706
|
+
secondary: [measureFactory.sum(DM.Admissions.Diagnosis_ID)],
|
|
1707
|
+
},
|
|
1708
|
+
styleOptions: {
|
|
1709
|
+
indicatorComponents: {
|
|
1710
|
+
title: {
|
|
1711
|
+
shouldBeShown: true,
|
|
1712
|
+
text: 'Total Cost_of_admission',
|
|
1713
|
+
},
|
|
1714
|
+
secondaryTitle: {
|
|
1715
|
+
text: 'Total Diagnosis_ID',
|
|
1716
|
+
},
|
|
1717
|
+
ticks: {
|
|
1718
|
+
shouldBeShown: true,
|
|
1719
|
+
},
|
|
1720
|
+
labels: {
|
|
1721
|
+
shouldBeShown: true,
|
|
1722
|
+
},
|
|
1723
|
+
},
|
|
1724
|
+
subtype: 'indicator/gauge',
|
|
1725
|
+
skin: 2,
|
|
1726
|
+
} as IndicatorStyleOptions,
|
|
1727
|
+
};
|
|
1728
|
+
|
|
1729
|
+
}
|
|
1730
|
+
* ```
|
|
1731
|
+
* <img src="media://angular-indicator-chart-example.png" width="800px" />
|
|
1732
|
+
* @group Charts
|
|
1733
|
+
*/
|
|
1734
|
+
class IndicatorChartComponent {
|
|
1735
|
+
constructor() {
|
|
1918
1736
|
/** @internal */
|
|
1919
|
-
this.chartType = '
|
|
1737
|
+
this.chartType = 'indicator';
|
|
1920
1738
|
}
|
|
1921
1739
|
}
|
|
1922
|
-
|
|
1923
|
-
|
|
1740
|
+
IndicatorChartComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: IndicatorChartComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1741
|
+
IndicatorChartComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: IndicatorChartComponent, selector: "csdk-indicator-chart", inputs: { dataSet: "dataSet", dataOptions: "dataOptions", filters: "filters", highlights: "highlights", styleOptions: "styleOptions", beforeRender: "beforeRender", dataReady: "dataReady" }, ngImport: i0, template: `
|
|
1924
1742
|
<csdk-chart
|
|
1925
1743
|
[chartType]="chartType"
|
|
1926
1744
|
[dataSet]="dataSet"
|
|
@@ -1930,15 +1748,12 @@ BoxplotChartComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0",
|
|
|
1930
1748
|
[styleOptions]="styleOptions"
|
|
1931
1749
|
[beforeRender]="beforeRender"
|
|
1932
1750
|
[dataReady]="dataReady"
|
|
1933
|
-
(dataPointClick)="dataPointClick.emit($any($event))"
|
|
1934
|
-
(dataPointContextMenu)="dataPointContextMenu.emit($any($event))"
|
|
1935
|
-
(dataPointsSelect)="dataPointsSelect.emit($any($event))"
|
|
1936
1751
|
/>
|
|
1937
1752
|
`, isInline: true, dependencies: [{ kind: "component", type: ChartComponent, selector: "csdk-chart", inputs: ["chartType", "dataSet", "dataOptions", "filters", "highlights", "styleOptions", "beforeRender", "dataReady"], outputs: ["dataPointClick", "dataPointContextMenu", "dataPointsSelect"] }] });
|
|
1938
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type:
|
|
1753
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: IndicatorChartComponent, decorators: [{
|
|
1939
1754
|
type: Component,
|
|
1940
1755
|
args: [{
|
|
1941
|
-
selector: 'csdk-
|
|
1756
|
+
selector: 'csdk-indicator-chart',
|
|
1942
1757
|
template: `
|
|
1943
1758
|
<csdk-chart
|
|
1944
1759
|
[chartType]="chartType"
|
|
@@ -1949,9 +1764,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
|
|
|
1949
1764
|
[styleOptions]="styleOptions"
|
|
1950
1765
|
[beforeRender]="beforeRender"
|
|
1951
1766
|
[dataReady]="dataReady"
|
|
1952
|
-
(dataPointClick)="dataPointClick.emit($any($event))"
|
|
1953
|
-
(dataPointContextMenu)="dataPointContextMenu.emit($any($event))"
|
|
1954
|
-
(dataPointsSelect)="dataPointsSelect.emit($any($event))"
|
|
1955
1767
|
/>
|
|
1956
1768
|
`,
|
|
1957
1769
|
}]
|
|
@@ -1969,33 +1781,28 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
|
|
|
1969
1781
|
type: Input
|
|
1970
1782
|
}], dataReady: [{
|
|
1971
1783
|
type: Input
|
|
1972
|
-
}], dataPointClick: [{
|
|
1973
|
-
type: Output
|
|
1974
|
-
}], dataPointContextMenu: [{
|
|
1975
|
-
type: Output
|
|
1976
|
-
}], dataPointsSelect: [{
|
|
1977
|
-
type: Output
|
|
1978
1784
|
}] } });
|
|
1979
1785
|
|
|
1980
1786
|
/**
|
|
1981
|
-
* A component
|
|
1982
|
-
* making it easy to identify daily patterns or anomalies
|
|
1787
|
+
* A component displaying data as a series of points connected by a line. Used to show trends or changes over time.
|
|
1983
1788
|
*
|
|
1984
1789
|
* @example
|
|
1985
1790
|
* ```html
|
|
1986
|
-
* <csdk-
|
|
1791
|
+
* <csdk-line-chart
|
|
1987
1792
|
* [dataSet]="chart.dataSet"
|
|
1988
1793
|
* [dataOptions]="chart.dataOptions"
|
|
1989
|
-
* [highlights]="
|
|
1990
|
-
* [
|
|
1794
|
+
* [highlights]="filters"
|
|
1795
|
+
* [beforeRender]="onBeforeRender"
|
|
1796
|
+
* (dataPointClick)="logArguments($event)"
|
|
1797
|
+
* (dataPointContextMenu)="logArguments($event)"
|
|
1798
|
+
* (dataPointsSelect)="logArguments($event)"
|
|
1991
1799
|
* />
|
|
1992
1800
|
* ```
|
|
1993
1801
|
* ```ts
|
|
1994
1802
|
import { Component } from '@angular/core';
|
|
1995
|
-
import { measureFactory, filterFactory } from '@sisense/sdk-data';
|
|
1996
|
-
import * as DM from '../../assets/sample-
|
|
1997
|
-
import type {
|
|
1998
|
-
|
|
1803
|
+
import { measureFactory, filterFactory, Filter } from '@sisense/sdk-data';
|
|
1804
|
+
import * as DM from '../../assets/sample-healthcare-model';
|
|
1805
|
+
import type { ChartType } from '@sisense/sdk-ui-angular';
|
|
1999
1806
|
@Component({
|
|
2000
1807
|
selector: 'app-analytics',
|
|
2001
1808
|
templateUrl: './analytics.component.html',
|
|
@@ -2003,54 +1810,57 @@ import type { CalendarHeatmapChartProps } from '@sisense/sdk-ui-angular';
|
|
|
2003
1810
|
})
|
|
2004
1811
|
export class AnalyticsComponent {
|
|
2005
1812
|
DM = DM;
|
|
1813
|
+
filters = [filterFactory.members(DM.Divisions.Divison_name, ['Cardiology', 'Neurology'])];
|
|
2006
1814
|
chart = {
|
|
1815
|
+
chartType: 'column' as ChartType,
|
|
2007
1816
|
dataSet: DM.DataSource,
|
|
2008
1817
|
dataOptions: {
|
|
2009
|
-
|
|
2010
|
-
value: measureFactory.sum(DM.
|
|
2011
|
-
|
|
2012
|
-
highlights: [
|
|
2013
|
-
filterFactory.dateRange(
|
|
2014
|
-
DM.Commerce.Date.Days,
|
|
2015
|
-
'2009-11-29',
|
|
2016
|
-
'2009-12-15'
|
|
2017
|
-
),
|
|
2018
|
-
],
|
|
2019
|
-
styleOptions: {
|
|
2020
|
-
viewType: 'quarter',
|
|
1818
|
+
category: [DM.Divisions.Divison_name],
|
|
1819
|
+
value: [measureFactory.sum(DM.Admissions.Cost_of_admission)],
|
|
1820
|
+
breakBy: [],
|
|
2021
1821
|
},
|
|
2022
1822
|
};
|
|
1823
|
+
|
|
1824
|
+
onBeforeRender(options: any) {
|
|
1825
|
+
console.log('beforeRender');
|
|
1826
|
+
console.log(options);
|
|
1827
|
+
return options;
|
|
1828
|
+
}
|
|
1829
|
+
|
|
1830
|
+
logArguments(...args: any[]) {
|
|
1831
|
+
console.log(args);
|
|
1832
|
+
}
|
|
2023
1833
|
}
|
|
2024
1834
|
* ```
|
|
2025
|
-
* <img src="media://angular-
|
|
1835
|
+
* <img src="media://angular-line-chart-example.png" width="800px" />
|
|
2026
1836
|
* @group Charts
|
|
2027
1837
|
*/
|
|
2028
|
-
class
|
|
1838
|
+
class LineChartComponent {
|
|
2029
1839
|
constructor() {
|
|
2030
1840
|
/**
|
|
2031
|
-
* {@inheritDoc @sisense/sdk-ui!
|
|
1841
|
+
* {@inheritDoc @sisense/sdk-ui!LineChartProps.onDataPointClick}
|
|
2032
1842
|
*
|
|
2033
1843
|
* @category Callbacks
|
|
2034
1844
|
*/
|
|
2035
1845
|
this.dataPointClick = new EventEmitter();
|
|
2036
1846
|
/**
|
|
2037
|
-
* {@inheritDoc @sisense/sdk-ui!
|
|
1847
|
+
* {@inheritDoc @sisense/sdk-ui!LineChartProps.onDataPointContextMenu}
|
|
2038
1848
|
*
|
|
2039
1849
|
* @category Callbacks
|
|
2040
1850
|
*/
|
|
2041
1851
|
this.dataPointContextMenu = new EventEmitter();
|
|
2042
1852
|
/**
|
|
2043
|
-
* {@inheritDoc @sisense/sdk-ui!
|
|
1853
|
+
* {@inheritDoc @sisense/sdk-ui!LineChartProps.onDataPointsSelected}
|
|
2044
1854
|
*
|
|
2045
1855
|
* @category Callbacks
|
|
2046
1856
|
*/
|
|
2047
1857
|
this.dataPointsSelect = new EventEmitter();
|
|
2048
1858
|
/** @internal */
|
|
2049
|
-
this.chartType = '
|
|
1859
|
+
this.chartType = 'line';
|
|
2050
1860
|
}
|
|
2051
1861
|
}
|
|
2052
|
-
|
|
2053
|
-
|
|
1862
|
+
LineChartComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: LineChartComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1863
|
+
LineChartComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: LineChartComponent, selector: "csdk-line-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: `
|
|
2054
1864
|
<csdk-chart
|
|
2055
1865
|
[chartType]="chartType"
|
|
2056
1866
|
[dataSet]="dataSet"
|
|
@@ -2065,10 +1875,10 @@ CalendarHeatmapChartComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "1
|
|
|
2065
1875
|
(dataPointsSelect)="dataPointsSelect.emit($any($event))"
|
|
2066
1876
|
/>
|
|
2067
1877
|
`, isInline: true, dependencies: [{ kind: "component", type: ChartComponent, selector: "csdk-chart", inputs: ["chartType", "dataSet", "dataOptions", "filters", "highlights", "styleOptions", "beforeRender", "dataReady"], outputs: ["dataPointClick", "dataPointContextMenu", "dataPointsSelect"] }] });
|
|
2068
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type:
|
|
1878
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: LineChartComponent, decorators: [{
|
|
2069
1879
|
type: Component,
|
|
2070
1880
|
args: [{
|
|
2071
|
-
selector: 'csdk-
|
|
1881
|
+
selector: 'csdk-line-chart',
|
|
2072
1882
|
template: `
|
|
2073
1883
|
<csdk-chart
|
|
2074
1884
|
[chartType]="chartType"
|
|
@@ -2108,12 +1918,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
|
|
|
2108
1918
|
}] } });
|
|
2109
1919
|
|
|
2110
1920
|
/**
|
|
2111
|
-
* A component representing
|
|
2112
|
-
*
|
|
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.
|
|
2113
1923
|
*
|
|
2114
1924
|
* @example
|
|
2115
1925
|
* ```html
|
|
2116
|
-
* <csdk-
|
|
1926
|
+
* <csdk-pie-chart
|
|
2117
1927
|
* [dataSet]="chart.dataSet"
|
|
2118
1928
|
* [dataOptions]="chart.dataOptions"
|
|
2119
1929
|
* [highlights]="filters"
|
|
@@ -2158,35 +1968,35 @@ export class AnalyticsComponent {
|
|
|
2158
1968
|
}
|
|
2159
1969
|
}
|
|
2160
1970
|
* ```
|
|
2161
|
-
* <img src="media://angular-
|
|
1971
|
+
* <img src="media://angular-pie-chart-example.png" width="800px" />
|
|
2162
1972
|
* @group Charts
|
|
2163
1973
|
*/
|
|
2164
|
-
class
|
|
1974
|
+
class PieChartComponent {
|
|
2165
1975
|
constructor() {
|
|
2166
1976
|
/**
|
|
2167
|
-
* {@inheritDoc @sisense/sdk-ui!
|
|
1977
|
+
* {@inheritDoc @sisense/sdk-ui!PieChartProps.onDataPointClick}
|
|
2168
1978
|
*
|
|
2169
1979
|
* @category Callbacks
|
|
2170
1980
|
*/
|
|
2171
1981
|
this.dataPointClick = new EventEmitter();
|
|
2172
1982
|
/**
|
|
2173
|
-
* {@inheritDoc @sisense/sdk-ui!
|
|
1983
|
+
* {@inheritDoc @sisense/sdk-ui!PieChartProps.onDataPointContextMenu}
|
|
2174
1984
|
*
|
|
2175
1985
|
* @category Callbacks
|
|
2176
1986
|
*/
|
|
2177
1987
|
this.dataPointContextMenu = new EventEmitter();
|
|
2178
1988
|
/**
|
|
2179
|
-
* {@inheritDoc @sisense/sdk-ui!
|
|
1989
|
+
* {@inheritDoc @sisense/sdk-ui!PieChartProps.onDataPointsSelected}
|
|
2180
1990
|
*
|
|
2181
1991
|
* @category Callbacks
|
|
2182
1992
|
*/
|
|
2183
1993
|
this.dataPointsSelect = new EventEmitter();
|
|
2184
1994
|
/** @internal */
|
|
2185
|
-
this.chartType = '
|
|
1995
|
+
this.chartType = 'pie';
|
|
2186
1996
|
}
|
|
2187
1997
|
}
|
|
2188
|
-
|
|
2189
|
-
|
|
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: `
|
|
2190
2000
|
<csdk-chart
|
|
2191
2001
|
[chartType]="chartType"
|
|
2192
2002
|
[dataSet]="dataSet"
|
|
@@ -2201,10 +2011,10 @@ ColumnChartComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", v
|
|
|
2201
2011
|
(dataPointsSelect)="dataPointsSelect.emit($any($event))"
|
|
2202
2012
|
/>
|
|
2203
2013
|
`, isInline: true, dependencies: [{ kind: "component", type: ChartComponent, selector: "csdk-chart", inputs: ["chartType", "dataSet", "dataOptions", "filters", "highlights", "styleOptions", "beforeRender", "dataReady"], outputs: ["dataPointClick", "dataPointContextMenu", "dataPointsSelect"] }] });
|
|
2204
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type:
|
|
2014
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: PieChartComponent, decorators: [{
|
|
2205
2015
|
type: Component,
|
|
2206
2016
|
args: [{
|
|
2207
|
-
selector: 'csdk-
|
|
2017
|
+
selector: 'csdk-pie-chart',
|
|
2208
2018
|
template: `
|
|
2209
2019
|
<csdk-chart
|
|
2210
2020
|
[chartType]="chartType"
|
|
@@ -2244,518 +2054,708 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
|
|
|
2244
2054
|
}] } });
|
|
2245
2055
|
|
|
2246
2056
|
/**
|
|
2247
|
-
*
|
|
2057
|
+
* Service for rendering components dynamically.
|
|
2248
2058
|
*
|
|
2249
|
-
* @
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
},
|
|
2282
|
-
};
|
|
2283
|
-
|
|
2284
|
-
onBeforeRender(options: any) {
|
|
2285
|
-
console.log('beforeRender');
|
|
2286
|
-
console.log(options);
|
|
2287
|
-
return options;
|
|
2288
|
-
}
|
|
2289
|
-
|
|
2290
|
-
logArguments(...args: any[]) {
|
|
2291
|
-
console.log(args);
|
|
2292
|
-
}
|
|
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
|
+
}
|
|
2293
2091
|
}
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
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
|
|
2297
2103
|
*/
|
|
2298
|
-
class
|
|
2299
|
-
constructor(
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
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);
|
|
2320
2136
|
}
|
|
2321
2137
|
}
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
[dataSet]="dataSet"
|
|
2327
|
-
[dataOptions]="dataOptions"
|
|
2328
|
-
[filters]="filters"
|
|
2329
|
-
[highlights]="highlights"
|
|
2330
|
-
[styleOptions]="styleOptions"
|
|
2331
|
-
[beforeRender]="beforeRender"
|
|
2332
|
-
[dataReady]="dataReady"
|
|
2333
|
-
(dataPointClick)="dataPointClick.emit($any($event))"
|
|
2334
|
-
(dataPointContextMenu)="dataPointContextMenu.emit($any($event))"
|
|
2335
|
-
(dataPointsSelect)="dataPointsSelect.emit($any($event))"
|
|
2336
|
-
/>
|
|
2337
|
-
`, isInline: true, dependencies: [{ kind: "component", type: ChartComponent, selector: "csdk-chart", inputs: ["chartType", "dataSet", "dataOptions", "filters", "highlights", "styleOptions", "beforeRender", "dataReady"], outputs: ["dataPointClick", "dataPointContextMenu", "dataPointsSelect"] }] });
|
|
2338
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: FunnelChartComponent, decorators: [{
|
|
2339
|
-
type: Component,
|
|
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,
|
|
2340
2142
|
args: [{
|
|
2341
|
-
|
|
2342
|
-
template: `
|
|
2343
|
-
<csdk-chart
|
|
2344
|
-
[chartType]="chartType"
|
|
2345
|
-
[dataSet]="dataSet"
|
|
2346
|
-
[dataOptions]="dataOptions"
|
|
2347
|
-
[filters]="filters"
|
|
2348
|
-
[highlights]="highlights"
|
|
2349
|
-
[styleOptions]="styleOptions"
|
|
2350
|
-
[beforeRender]="beforeRender"
|
|
2351
|
-
[dataReady]="dataReady"
|
|
2352
|
-
(dataPointClick)="dataPointClick.emit($any($event))"
|
|
2353
|
-
(dataPointContextMenu)="dataPointContextMenu.emit($any($event))"
|
|
2354
|
-
(dataPointsSelect)="dataPointsSelect.emit($any($event))"
|
|
2355
|
-
/>
|
|
2356
|
-
`,
|
|
2143
|
+
providedIn: 'root',
|
|
2357
2144
|
}]
|
|
2358
|
-
}],
|
|
2359
|
-
type: Input
|
|
2360
|
-
}], dataOptions: [{
|
|
2361
|
-
type: Input
|
|
2362
|
-
}], filters: [{
|
|
2363
|
-
type: Input
|
|
2364
|
-
}], highlights: [{
|
|
2365
|
-
type: Input
|
|
2366
|
-
}], styleOptions: [{
|
|
2367
|
-
type: Input
|
|
2368
|
-
}], beforeRender: [{
|
|
2369
|
-
type: Input
|
|
2370
|
-
}], dataReady: [{
|
|
2371
|
-
type: Input
|
|
2372
|
-
}], dataPointClick: [{
|
|
2373
|
-
type: Output
|
|
2374
|
-
}], dataPointContextMenu: [{
|
|
2375
|
-
type: Output
|
|
2376
|
-
}], dataPointsSelect: [{
|
|
2377
|
-
type: Output
|
|
2378
|
-
}] } });
|
|
2379
|
-
|
|
2380
|
-
/**
|
|
2381
|
-
* A component that provides various options for displaying one or two numeric values as a number, gauge or ticker.
|
|
2382
|
-
*
|
|
2383
|
-
* @example
|
|
2384
|
-
* ```html
|
|
2385
|
-
* <csdk-indicator-chart
|
|
2386
|
-
* [dataSet]="indicator.dataSet"
|
|
2387
|
-
* [dataOptions]="indicator.dataOptions"
|
|
2388
|
-
* [filters]="filters"
|
|
2389
|
-
* [styleOptions]="indicator.styleOptions"
|
|
2390
|
-
* />
|
|
2391
|
-
* ```
|
|
2392
|
-
* ```ts
|
|
2393
|
-
import { Component } from '@angular/core';
|
|
2394
|
-
import { measureFactory, filterFactory } from '@sisense/sdk-data';
|
|
2395
|
-
import * as DM from '../../assets/sample-healthcare-model';
|
|
2396
|
-
import type { IndicatorStyleOptions } from '@sisense/sdk-ui-angular';
|
|
2145
|
+
}], ctorParameters: function () { return [{ type: DynamicRenderer }]; } });
|
|
2397
2146
|
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
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
|
+
}
|
|
2432
2189
|
|
|
2190
|
+
function translateToPreactDashboardProps(dashboardProps) {
|
|
2191
|
+
return {
|
|
2192
|
+
...dashboardProps,
|
|
2193
|
+
widgets: dashboardProps.widgets.map(translateToPreactWidgetProps),
|
|
2194
|
+
};
|
|
2433
2195
|
}
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
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
|
|
2437
2210
|
*/
|
|
2438
|
-
class
|
|
2439
|
-
constructor() {
|
|
2440
|
-
|
|
2441
|
-
|
|
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
|
+
};
|
|
2442
2328
|
}
|
|
2443
|
-
}
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
[highlights]="highlights"
|
|
2452
|
-
[styleOptions]="styleOptions"
|
|
2453
|
-
[beforeRender]="beforeRender"
|
|
2454
|
-
[dataReady]="dataReady"
|
|
2455
|
-
/>
|
|
2456
|
-
`, isInline: true, dependencies: [{ kind: "component", type: ChartComponent, selector: "csdk-chart", inputs: ["chartType", "dataSet", "dataOptions", "filters", "highlights", "styleOptions", "beforeRender", "dataReady"], outputs: ["dataPointClick", "dataPointContextMenu", "dataPointsSelect"] }] });
|
|
2457
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: IndicatorChartComponent, decorators: [{
|
|
2458
|
-
type: Component,
|
|
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,
|
|
2459
2337
|
args: [{
|
|
2460
|
-
|
|
2461
|
-
template: `
|
|
2462
|
-
<csdk-chart
|
|
2463
|
-
[chartType]="chartType"
|
|
2464
|
-
[dataSet]="dataSet"
|
|
2465
|
-
[dataOptions]="dataOptions"
|
|
2466
|
-
[filters]="filters"
|
|
2467
|
-
[highlights]="highlights"
|
|
2468
|
-
[styleOptions]="styleOptions"
|
|
2469
|
-
[beforeRender]="beforeRender"
|
|
2470
|
-
[dataReady]="dataReady"
|
|
2471
|
-
/>
|
|
2472
|
-
`,
|
|
2338
|
+
providedIn: 'root',
|
|
2473
2339
|
}]
|
|
2474
|
-
}],
|
|
2475
|
-
type: Input
|
|
2476
|
-
}], dataOptions: [{
|
|
2477
|
-
type: Input
|
|
2478
|
-
}], filters: [{
|
|
2479
|
-
type: Input
|
|
2480
|
-
}], highlights: [{
|
|
2481
|
-
type: Input
|
|
2482
|
-
}], styleOptions: [{
|
|
2483
|
-
type: Input
|
|
2484
|
-
}], beforeRender: [{
|
|
2485
|
-
type: Input
|
|
2486
|
-
}], dataReady: [{
|
|
2487
|
-
type: Input
|
|
2488
|
-
}] } });
|
|
2340
|
+
}], ctorParameters: function () { return [{ type: SisenseContextService }]; } });
|
|
2489
2341
|
|
|
2490
2342
|
/**
|
|
2491
|
-
*
|
|
2343
|
+
* Service for working with filter.
|
|
2492
2344
|
*
|
|
2493
|
-
* @
|
|
2494
|
-
* ```html
|
|
2495
|
-
* <csdk-line-chart
|
|
2496
|
-
* [dataSet]="chart.dataSet"
|
|
2497
|
-
* [dataOptions]="chart.dataOptions"
|
|
2498
|
-
* [highlights]="filters"
|
|
2499
|
-
* [beforeRender]="onBeforeRender"
|
|
2500
|
-
* (dataPointClick)="logArguments($event)"
|
|
2501
|
-
* (dataPointContextMenu)="logArguments($event)"
|
|
2502
|
-
* (dataPointsSelect)="logArguments($event)"
|
|
2503
|
-
* />
|
|
2504
|
-
* ```
|
|
2505
|
-
* ```ts
|
|
2506
|
-
import { Component } from '@angular/core';
|
|
2507
|
-
import { measureFactory, filterFactory, Filter } from '@sisense/sdk-data';
|
|
2508
|
-
import * as DM from '../../assets/sample-healthcare-model';
|
|
2509
|
-
import type { ChartType } from '@sisense/sdk-ui-angular';
|
|
2510
|
-
@Component({
|
|
2511
|
-
selector: 'app-analytics',
|
|
2512
|
-
templateUrl: './analytics.component.html',
|
|
2513
|
-
styleUrls: ['./analytics.component.scss'],
|
|
2514
|
-
})
|
|
2515
|
-
export class AnalyticsComponent {
|
|
2516
|
-
DM = DM;
|
|
2517
|
-
filters = [filterFactory.members(DM.Divisions.Divison_name, ['Cardiology', 'Neurology'])];
|
|
2518
|
-
chart = {
|
|
2519
|
-
chartType: 'column' as ChartType,
|
|
2520
|
-
dataSet: DM.DataSource,
|
|
2521
|
-
dataOptions: {
|
|
2522
|
-
category: [DM.Divisions.Divison_name],
|
|
2523
|
-
value: [measureFactory.sum(DM.Admissions.Cost_of_admission)],
|
|
2524
|
-
breakBy: [],
|
|
2525
|
-
},
|
|
2526
|
-
};
|
|
2527
|
-
|
|
2528
|
-
onBeforeRender(options: any) {
|
|
2529
|
-
console.log('beforeRender');
|
|
2530
|
-
console.log(options);
|
|
2531
|
-
return options;
|
|
2532
|
-
}
|
|
2533
|
-
|
|
2534
|
-
logArguments(...args: any[]) {
|
|
2535
|
-
console.log(args);
|
|
2536
|
-
}
|
|
2537
|
-
}
|
|
2538
|
-
* ```
|
|
2539
|
-
* <img src="media://angular-line-chart-example.png" width="800px" />
|
|
2540
|
-
* @group Charts
|
|
2345
|
+
* @group Filters
|
|
2541
2346
|
*/
|
|
2542
|
-
class
|
|
2543
|
-
constructor() {
|
|
2544
|
-
|
|
2545
|
-
* {@inheritDoc @sisense/sdk-ui!LineChartProps.onDataPointClick}
|
|
2546
|
-
*
|
|
2547
|
-
* @category Callbacks
|
|
2548
|
-
*/
|
|
2549
|
-
this.dataPointClick = new EventEmitter();
|
|
2550
|
-
/**
|
|
2551
|
-
* {@inheritDoc @sisense/sdk-ui!LineChartProps.onDataPointContextMenu}
|
|
2552
|
-
*
|
|
2553
|
-
* @category Callbacks
|
|
2554
|
-
*/
|
|
2555
|
-
this.dataPointContextMenu = new EventEmitter();
|
|
2556
|
-
/**
|
|
2557
|
-
* {@inheritDoc @sisense/sdk-ui!LineChartProps.onDataPointsSelected}
|
|
2558
|
-
*
|
|
2559
|
-
* @category Callbacks
|
|
2560
|
-
*/
|
|
2561
|
-
this.dataPointsSelect = new EventEmitter();
|
|
2562
|
-
/** @internal */
|
|
2563
|
-
this.chartType = 'line';
|
|
2347
|
+
let FilterService = class FilterService {
|
|
2348
|
+
constructor(sisenseContextService) {
|
|
2349
|
+
this.sisenseContextService = sisenseContextService;
|
|
2564
2350
|
}
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
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,
|
|
2584
2404
|
args: [{
|
|
2585
|
-
|
|
2586
|
-
template: `
|
|
2587
|
-
<csdk-chart
|
|
2588
|
-
[chartType]="chartType"
|
|
2589
|
-
[dataSet]="dataSet"
|
|
2590
|
-
[dataOptions]="dataOptions"
|
|
2591
|
-
[filters]="filters"
|
|
2592
|
-
[highlights]="highlights"
|
|
2593
|
-
[styleOptions]="styleOptions"
|
|
2594
|
-
[beforeRender]="beforeRender"
|
|
2595
|
-
[dataReady]="dataReady"
|
|
2596
|
-
(dataPointClick)="dataPointClick.emit($any($event))"
|
|
2597
|
-
(dataPointContextMenu)="dataPointContextMenu.emit($any($event))"
|
|
2598
|
-
(dataPointsSelect)="dataPointsSelect.emit($any($event))"
|
|
2599
|
-
/>
|
|
2600
|
-
`,
|
|
2405
|
+
providedIn: 'root',
|
|
2601
2406
|
}]
|
|
2602
|
-
}],
|
|
2603
|
-
type: Input
|
|
2604
|
-
}], dataOptions: [{
|
|
2605
|
-
type: Input
|
|
2606
|
-
}], filters: [{
|
|
2607
|
-
type: Input
|
|
2608
|
-
}], highlights: [{
|
|
2609
|
-
type: Input
|
|
2610
|
-
}], styleOptions: [{
|
|
2611
|
-
type: Input
|
|
2612
|
-
}], beforeRender: [{
|
|
2613
|
-
type: Input
|
|
2614
|
-
}], dataReady: [{
|
|
2615
|
-
type: Input
|
|
2616
|
-
}], dataPointClick: [{
|
|
2617
|
-
type: Output
|
|
2618
|
-
}], dataPointContextMenu: [{
|
|
2619
|
-
type: Output
|
|
2620
|
-
}], dataPointsSelect: [{
|
|
2621
|
-
type: Output
|
|
2622
|
-
}] } });
|
|
2407
|
+
}], ctorParameters: function () { return [{ type: SisenseContextService }]; } });
|
|
2623
2408
|
|
|
2624
2409
|
/**
|
|
2625
|
-
*
|
|
2626
|
-
* with each slice representing a proportion of the total.
|
|
2410
|
+
* Service for working with Sisense Fusion hierarchies.
|
|
2627
2411
|
*
|
|
2628
|
-
* @
|
|
2629
|
-
*
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
dataOptions: {
|
|
2658
|
-
category: [DM.Divisions.Divison_name],
|
|
2659
|
-
value: [measureFactory.sum(DM.Admissions.Cost_of_admission)],
|
|
2660
|
-
breakBy: [],
|
|
2661
|
-
},
|
|
2662
|
-
};
|
|
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 }]; } });
|
|
2663
2441
|
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
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 }]; } });
|
|
2669
2589
|
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
*
|
|
2675
|
-
* <img src="media://angular-pie-chart-example.png" width="800px" />
|
|
2676
|
-
* @group Charts
|
|
2590
|
+
/**
|
|
2591
|
+
* Service for working with Sisense Fusion widgets.
|
|
2592
|
+
*
|
|
2593
|
+
* @group Fusion Assets
|
|
2594
|
+
* @fusionEmbed
|
|
2677
2595
|
*/
|
|
2678
|
-
class
|
|
2679
|
-
constructor() {
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
*
|
|
2683
|
-
* @category Callbacks
|
|
2684
|
-
*/
|
|
2685
|
-
this.dataPointClick = new EventEmitter();
|
|
2686
|
-
/**
|
|
2687
|
-
* {@inheritDoc @sisense/sdk-ui!PieChartProps.onDataPointContextMenu}
|
|
2688
|
-
*
|
|
2689
|
-
* @category Callbacks
|
|
2690
|
-
*/
|
|
2691
|
-
this.dataPointContextMenu = new EventEmitter();
|
|
2692
|
-
/**
|
|
2693
|
-
* {@inheritDoc @sisense/sdk-ui!PieChartProps.onDataPointsSelected}
|
|
2694
|
-
*
|
|
2695
|
-
* @category Callbacks
|
|
2696
|
-
*/
|
|
2697
|
-
this.dataPointsSelect = new EventEmitter();
|
|
2698
|
-
/** @internal */
|
|
2699
|
-
this.chartType = 'pie';
|
|
2596
|
+
let WidgetService = class WidgetService {
|
|
2597
|
+
constructor(sisenseContextService, themeService) {
|
|
2598
|
+
this.sisenseContextService = sisenseContextService;
|
|
2599
|
+
this.themeService = themeService;
|
|
2700
2600
|
}
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
|
|
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,
|
|
2720
2755
|
args: [{
|
|
2721
|
-
|
|
2722
|
-
template: `
|
|
2723
|
-
<csdk-chart
|
|
2724
|
-
[chartType]="chartType"
|
|
2725
|
-
[dataSet]="dataSet"
|
|
2726
|
-
[dataOptions]="dataOptions"
|
|
2727
|
-
[filters]="filters"
|
|
2728
|
-
[highlights]="highlights"
|
|
2729
|
-
[styleOptions]="styleOptions"
|
|
2730
|
-
[beforeRender]="beforeRender"
|
|
2731
|
-
[dataReady]="dataReady"
|
|
2732
|
-
(dataPointClick)="dataPointClick.emit($any($event))"
|
|
2733
|
-
(dataPointContextMenu)="dataPointContextMenu.emit($any($event))"
|
|
2734
|
-
(dataPointsSelect)="dataPointsSelect.emit($any($event))"
|
|
2735
|
-
/>
|
|
2736
|
-
`,
|
|
2756
|
+
providedIn: 'root',
|
|
2737
2757
|
}]
|
|
2738
|
-
}],
|
|
2739
|
-
type: Input
|
|
2740
|
-
}], dataOptions: [{
|
|
2741
|
-
type: Input
|
|
2742
|
-
}], filters: [{
|
|
2743
|
-
type: Input
|
|
2744
|
-
}], highlights: [{
|
|
2745
|
-
type: Input
|
|
2746
|
-
}], styleOptions: [{
|
|
2747
|
-
type: Input
|
|
2748
|
-
}], beforeRender: [{
|
|
2749
|
-
type: Input
|
|
2750
|
-
}], dataReady: [{
|
|
2751
|
-
type: Input
|
|
2752
|
-
}], dataPointClick: [{
|
|
2753
|
-
type: Output
|
|
2754
|
-
}], dataPointContextMenu: [{
|
|
2755
|
-
type: Output
|
|
2756
|
-
}], dataPointsSelect: [{
|
|
2757
|
-
type: Output
|
|
2758
|
-
}] } });
|
|
2758
|
+
}], ctorParameters: function () { return [{ type: SisenseContextService }, { type: ThemeService }]; } });
|
|
2759
2759
|
|
|
2760
2760
|
/**
|
|
2761
2761
|
* Pivot Table with and pagination.
|