@c8y/ngx-components 1024.18.1 → 1024.18.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/fesm2022/c8y-ngx-components-actility-device-registration.mjs +1 -1
  2. package/fesm2022/c8y-ngx-components-actility-device-registration.mjs.map +1 -1
  3. package/fesm2022/c8y-ngx-components-asset-properties.mjs +67 -20
  4. package/fesm2022/c8y-ngx-components-asset-properties.mjs.map +1 -1
  5. package/fesm2022/c8y-ngx-components-assets-navigator.mjs +75 -13
  6. package/fesm2022/c8y-ngx-components-assets-navigator.mjs.map +1 -1
  7. package/fesm2022/c8y-ngx-components-branding-shared-lazy-add-branding-modal.mjs +2 -4
  8. package/fesm2022/c8y-ngx-components-branding-shared-lazy-add-branding-modal.mjs.map +1 -1
  9. package/fesm2022/c8y-ngx-components-branding-shared-lazy.mjs +6 -8
  10. package/fesm2022/c8y-ngx-components-branding-shared-lazy.mjs.map +1 -1
  11. package/fesm2022/c8y-ngx-components-context-dashboard.mjs +98 -19
  12. package/fesm2022/c8y-ngx-components-context-dashboard.mjs.map +1 -1
  13. package/fesm2022/c8y-ngx-components-dashboard-manager.mjs +4 -4
  14. package/fesm2022/c8y-ngx-components-dashboard-manager.mjs.map +1 -1
  15. package/fesm2022/c8y-ngx-components-datapoint-explorer-view.mjs +7 -7
  16. package/fesm2022/c8y-ngx-components-datapoint-explorer-view.mjs.map +1 -1
  17. package/fesm2022/c8y-ngx-components-datapoints-export-selector.mjs +5 -3
  18. package/fesm2022/c8y-ngx-components-datapoints-export-selector.mjs.map +1 -1
  19. package/fesm2022/c8y-ngx-components-echart-models.mjs.map +1 -1
  20. package/fesm2022/c8y-ngx-components-echart.mjs +52 -7
  21. package/fesm2022/c8y-ngx-components-echart.mjs.map +1 -1
  22. package/fesm2022/c8y-ngx-components-ecosystem.mjs +1 -1
  23. package/fesm2022/c8y-ngx-components-ecosystem.mjs.map +1 -1
  24. package/fesm2022/c8y-ngx-components-file-preview.mjs +2 -2
  25. package/fesm2022/c8y-ngx-components-file-preview.mjs.map +1 -1
  26. package/fesm2022/c8y-ngx-components-icon-selector.mjs +6 -6
  27. package/fesm2022/c8y-ngx-components-icon-selector.mjs.map +1 -1
  28. package/fesm2022/c8y-ngx-components-loriot-device-registration.mjs +1 -1
  29. package/fesm2022/c8y-ngx-components-loriot-device-registration.mjs.map +1 -1
  30. package/fesm2022/c8y-ngx-components-operation-picker.mjs +2 -2
  31. package/fesm2022/c8y-ngx-components-operation-picker.mjs.map +1 -1
  32. package/fesm2022/c8y-ngx-components-register-device.mjs +4 -4
  33. package/fesm2022/c8y-ngx-components-register-device.mjs.map +1 -1
  34. package/fesm2022/c8y-ngx-components-remote-access-configurations.mjs +2 -3
  35. package/fesm2022/c8y-ngx-components-remote-access-configurations.mjs.map +1 -1
  36. package/fesm2022/c8y-ngx-components-remote-access-shared.mjs +2 -2
  37. package/fesm2022/c8y-ngx-components-remote-access-shared.mjs.map +1 -1
  38. package/fesm2022/c8y-ngx-components-remote-access-ssh-remote-access-ssh-endpoint-modal.mjs +2 -2
  39. package/fesm2022/c8y-ngx-components-remote-access-ssh-remote-access-ssh-endpoint-modal.mjs.map +1 -1
  40. package/fesm2022/c8y-ngx-components-remote-access-vnc-remote-access-vnc-endpoint-modal.mjs +2 -4
  41. package/fesm2022/c8y-ngx-components-remote-access-vnc-remote-access-vnc-endpoint-modal.mjs.map +1 -1
  42. package/fesm2022/c8y-ngx-components-remote-access-vnc-vnc-viewer.mjs +2 -3
  43. package/fesm2022/c8y-ngx-components-remote-access-vnc-vnc-viewer.mjs.map +1 -1
  44. package/fesm2022/c8y-ngx-components-sigfox-device-registration.mjs +1 -1
  45. package/fesm2022/c8y-ngx-components-sigfox-device-registration.mjs.map +1 -1
  46. package/fesm2022/c8y-ngx-components-static-assets-modal.mjs +2 -2
  47. package/fesm2022/c8y-ngx-components-static-assets-modal.mjs.map +1 -1
  48. package/fesm2022/c8y-ngx-components-translation-editor-lazy.mjs +3 -4
  49. package/fesm2022/c8y-ngx-components-translation-editor-lazy.mjs.map +1 -1
  50. package/fesm2022/c8y-ngx-components-widgets-definitions-scada.mjs +10 -1
  51. package/fesm2022/c8y-ngx-components-widgets-definitions-scada.mjs.map +1 -1
  52. package/fesm2022/c8y-ngx-components-widgets-implementations-asset-table.mjs +4 -4
  53. package/fesm2022/c8y-ngx-components-widgets-implementations-asset-table.mjs.map +1 -1
  54. package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-graph.mjs +18 -3
  55. package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-graph.mjs.map +1 -1
  56. package/fesm2022/c8y-ngx-components-widgets-implementations-scada.mjs +1 -1
  57. package/fesm2022/c8y-ngx-components-widgets-implementations-scada.mjs.map +1 -1
  58. package/fesm2022/c8y-ngx-components.mjs +59 -19
  59. package/fesm2022/c8y-ngx-components.mjs.map +1 -1
  60. package/locales/de.po +3 -2
  61. package/locales/es.po +3 -3
  62. package/locales/fr.po +3 -3
  63. package/locales/ja_JP.po +2 -2
  64. package/locales/ko.po +3 -3
  65. package/locales/locales.pot +1 -1
  66. package/locales/nl.po +3 -3
  67. package/locales/pl.po +2 -3
  68. package/locales/pt_BR.po +2 -3
  69. package/locales/zh_CN.po +2 -2
  70. package/locales/zh_TW.po +3 -3
  71. package/package.json +1 -1
  72. package/types/c8y-ngx-components-asset-properties.d.ts +9 -1
  73. package/types/c8y-ngx-components-asset-properties.d.ts.map +1 -1
  74. package/types/c8y-ngx-components-assets-navigator.d.ts +30 -3
  75. package/types/c8y-ngx-components-assets-navigator.d.ts.map +1 -1
  76. package/types/c8y-ngx-components-branding-shared-lazy-add-branding-modal.d.ts.map +1 -1
  77. package/types/c8y-ngx-components-context-dashboard.d.ts +44 -1
  78. package/types/c8y-ngx-components-context-dashboard.d.ts.map +1 -1
  79. package/types/c8y-ngx-components-echart-models.d.ts +9 -0
  80. package/types/c8y-ngx-components-echart-models.d.ts.map +1 -1
  81. package/types/c8y-ngx-components-echart.d.ts +32 -5
  82. package/types/c8y-ngx-components-echart.d.ts.map +1 -1
  83. package/types/c8y-ngx-components-remote-access-vnc-remote-access-vnc-endpoint-modal.d.ts.map +1 -1
  84. package/types/c8y-ngx-components-widgets-implementations-datapoints-graph.d.ts +6 -0
  85. package/types/c8y-ngx-components-widgets-implementations-datapoints-graph.d.ts.map +1 -1
  86. package/types/c8y-ngx-components.d.ts +50 -2
  87. package/types/c8y-ngx-components.d.ts.map +1 -1
@@ -232,7 +232,7 @@ class DatapointsGraphWidgetConfigComponent {
232
232
  ChartAlarmsService,
233
233
  ChartHelpersService,
234
234
  WidgetTimeContextDateRangeService
235
- ], viewQueries: [{ propertyName: "previewMapSet", first: true, predicate: ["dataPointsGraphPreview"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<form [formGroup]=\"formGroup\">\n <fieldset class=\"c8y-fieldset\">\n <legend>{{ 'Formatting' | translate }}</legend>\n <c8y-form-group class=\"form-group-sm\">\n <label\n [title]=\"'Number of decimal places' | translate\"\n translate\n >\n Number of decimal places\n </label>\n <input\n class=\"form-control\"\n name=\"numberOfDecimalPlaces\"\n type=\"number\"\n formControlName=\"numberOfDecimalPlaces\"\n [placeholder]=\"'e.g. {{ example }}' | translate: { example: 1 }\"\n />\n <c8y-messages\n [show]=\"\n formGroup.controls?.numberOfDecimalPlaces?.touched &&\n formGroup?.controls?.numberOfDecimalPlaces?.errors\n \"\n ></c8y-messages>\n </c8y-form-group>\n <c8y-form-group class=\"form-group-sm\">\n <label>\n {{ 'Data point legend display' | translate }}\n </label>\n <div\n class=\"c8y-select-wrapper\"\n [formGroup]=\"formGroup\"\n >\n <select\n class=\"form-control\"\n [title]=\"'Data point legend display' | translate\"\n id=\"dataPointLegendDisplay\"\n formControlName=\"dataPointLegendDisplay\"\n >\n @for (option of legendDisplayOptions; track option) {\n <option [ngValue]=\"option.value\">\n {{ option.label | translate }}\n </option>\n }\n </select>\n </div>\n </c8y-form-group>\n </fieldset>\n\n <fieldset class=\"c8y-fieldset\">\n <legend>{{ 'Display options' | translate }}</legend>\n <fieldset class=\"c8y-fieldset\">\n <legend>{{ 'Axis' | translate }}</legend>\n <c8y-form-group class=\"m-b-8 form-group-sm\">\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Y-axis helper lines' | translate\"\n >\n <input\n name=\"yAxisSplitLines\"\n type=\"checkbox\"\n formControlName=\"yAxisSplitLines\"\n />\n <span></span>\n <span translate>Y-axis helper lines</span>\n </label>\n <label\n class=\"c8y-checkbox\"\n [title]=\"'X-axis helper lines' | translate\"\n >\n <input\n name=\"xAxisSplitLines\"\n type=\"checkbox\"\n formControlName=\"xAxisSplitLines\"\n />\n <span></span>\n <span translate>X-axis helper lines</span>\n </label>\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Merge matching data points into a single axis' | translate\"\n >\n <input\n name=\"mergeMatchingDatapoints\"\n type=\"checkbox\"\n formControlName=\"mergeMatchingDatapoints\"\n />\n <span></span>\n <span translate>Merge matching data points into a single axis</span>\n <button\n class=\"btn-help\"\n [attr.aria-label]=\"\n 'Data points with the same min and max values will be merged into a single axis. The values must be defined in the data point configuration.'\n | translate\n \"\n [popover]=\"\n 'Data points with the same min and max values will be merged into a single axis. The values must be defined in the data point configuration.'\n | translate\n \"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n (click)=\"$event.stopPropagation()\"\n [adaptivePosition]=\"false\"\n ></button>\n </label>\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Force merge all data points into a single axis' | translate\"\n >\n <input\n name=\"forceMergeDatapoints\"\n type=\"checkbox\"\n formControlName=\"forceMergeDatapoints\"\n />\n <span></span>\n <span translate>Force merge all data points into a single axis</span>\n <button\n class=\"btn-help\"\n [attr.aria-label]=\"\n 'All axes will be force merged to a single axis with the scale being set to the max and min value of all axes. It\\'s recommended to use this option for data points with similar values.'\n | translate\n \"\n [popover]=\"\n 'All axes will be force merged to a single axis with the scale being set to the max and min value of all axes. It\\'s recommended to use this option for data points with similar values.'\n | translate\n \"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n (click)=\"$event.stopPropagation()\"\n [adaptivePosition]=\"false\"\n ></button>\n </label>\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Set Y-axis start to 0' | translate\"\n >\n <input\n name=\"setYaxisStartToZero\"\n type=\"checkbox\"\n formControlName=\"setYaxisStartToZero\"\n />\n <span></span>\n <span translate>Set Y-axis start to 0</span>\n <button\n class=\"btn-help\"\n [attr.aria-label]=\"\n 'Sets the Y-axis minimum to 0 for all data points with positive values. If any data point includes negative values, the axis may still extend below 0. Explicitly configured minimum and maximum values take precedence over this option.'\n | translate\n \"\n [popover]=\"\n 'Sets the Y-axis minimum to 0 for all data points with positive values. If any data point includes negative values, the axis may still extend below 0. Explicitly configured minimum and maximum values take precedence over this option.'\n | translate\n \"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n (click)=\"$event.stopPropagation()\"\n [adaptivePosition]=\"false\"\n ></button>\n </label>\n </c8y-form-group>\n </fieldset>\n <fieldset class=\"c8y-fieldset\">\n <legend>{{ 'Alarms & events' | translate }}</legend>\n <c8y-form-group class=\"m-b-8 form-group-sm\">\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Show vertical line on every occurrence' | translate\"\n >\n <input\n name=\"displayMarkedLine\"\n type=\"checkbox\"\n formControlName=\"displayMarkedLine\"\n />\n <span></span>\n <span translate>Show vertical line on every occurrence</span>\n </label>\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Show icon when triggered' | translate\"\n >\n <input\n name=\"displayMarkedPoint\"\n type=\"checkbox\"\n formControlName=\"displayMarkedPoint\"\n />\n <span></span>\n <span translate>Show icon when triggered</span>\n @if (alarmsOrEventsHaveNoMatchingDps) {\n <button\n class=\"btn-clean m-l-8\"\n [attr.aria-label]=\"\n 'Some alarms or events have no matching data points. No icons will be shown for them.'\n | translate\n \"\n [tooltip]=\"\n 'Some alarms or events have no matching data points. No icons will be shown for them.'\n | translate\n \"\n container=\"body\"\n type=\"button\"\n (click)=\"$event.stopPropagation()\"\n [adaptivePosition]=\"false\"\n >\n <i\n class=\"text-warning\"\n c8yIcon=\"exclamation-triangle\"\n ></i>\n </button>\n }\n </label>\n </c8y-form-group>\n </fieldset>\n <fieldset class=\"c8y-fieldset\">\n <legend>{{ 'Chart' | translate }}</legend>\n <c8y-form-group class=\"m-b-8 form-group-sm\">\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Show labels and units' | translate\"\n >\n <input\n name=\"showLabelAndUnit\"\n type=\"checkbox\"\n formControlName=\"showLabelAndUnit\"\n />\n <span></span>\n <span translate>Display labels and units on Y-axis</span>\n </label>\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Show slider' | translate\"\n >\n <input\n name=\"showSlider\"\n type=\"checkbox\"\n formControlName=\"showSlider\"\n />\n <span></span>\n <span translate>Show slider</span>\n </label>\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Show smooth lines' | translate\"\n >\n <input\n name=\"smoothLines\"\n type=\"checkbox\"\n formControlName=\"smoothLines\"\n />\n <span></span>\n <span translate>Show smooth lines</span>\n </label>\n </c8y-form-group>\n </fieldset>\n </fieldset>\n</form>\n\n<ng-template #dataPointsGraphPreview>\n @if (config?.displayMode && config.displayMode !== 'dashboard') {\n <c8y-local-controls\n [controls]=\"widgetControls\"\n [displayMode]=\"config.displayMode\"\n [config]=\"previewContextConfig()\"\n [disabled]=\"true\"\n ></c8y-local-controls>\n }\n\n @if (activeDatapointsExists) {\n <c8y-charts\n class=\"d-block p-relative\"\n [config]=\"config\"\n [alerts]=\"alerts\"\n [chartViewContext]=\"chartViewContext\"\n (timeRangeChangeOnRealtime)=\"updateTimeRangeOnRealtime($event)\"\n (configChangeOnZoomOut)=\"updateDashboardTimeContext($event)\"\n (updateAggregatedSliderDatapoint)=\"updateAggregatedSliderDatapoint($event)\"\n ></c8y-charts>\n }\n\n @if (!activeDatapointsExists) {\n <c8y-ui-empty-state\n class=\"d-block m-t-24\"\n [icon]=\"'search'\"\n [title]=\"'No data points selected' | translate\"\n [subtitle]=\"'Select data point to render content' | translate\"\n data-cy=\"datapoints-graph-list--empty-state-no-data-point-selected\"\n >\n <p c8y-guide-docs>\n <small\n translate\n ngNonBindable\n >\n Find out more in the\n <a c8y-guide-href=\"/docs/cockpit/widgets-collection/#data-point-graph\">\n user documentation</a\n >.\n </small>\n </p>\n </c8y-ui-empty-state>\n }\n</ng-template>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: i1.EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "directive", type: i1.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i1.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "ngmodule", type: CoreModule }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "component", type: i1.FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "component", type: i1.MessagesComponent, selector: "c8y-messages", inputs: ["show", "defaults", "helpMessage", "additionalMessages"] }, { kind: "directive", type: i1.RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "directive", type: i1.GuideHrefDirective, selector: "[c8y-guide-href]", inputs: ["c8y-guide-href"] }, { kind: "component", type: i1.GuideDocsComponent, selector: "[c8y-guide-docs]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i3.TooltipDirective, selector: "[tooltip], [tooltipHtml]", inputs: ["adaptivePosition", "tooltip", "placement", "triggers", "container", "containerClass", "boundariesElement", "isOpen", "isDisabled", "delay", "tooltipHtml", "tooltipPlacement", "tooltipIsOpen", "tooltipEnable", "tooltipAppendToBody", "tooltipAnimation", "tooltipClass", "tooltipContext", "tooltipPopupDelay", "tooltipFadeDuration", "tooltipTrigger"], outputs: ["tooltipChange", "onShown", "onHidden", "tooltipStateChanged"], exportAs: ["bs-tooltip"] }, { kind: "ngmodule", type: PopoverModule }, { kind: "directive", type: i4.PopoverDirective, selector: "[popover]", inputs: ["adaptivePosition", "boundariesElement", "popover", "popoverContext", "popoverTitle", "placement", "outsideClick", "triggers", "container", "containerClass", "isOpen", "delay"], outputs: ["onShown", "onHidden"], exportAs: ["bs-popover"] }, { kind: "component", type: ChartsComponent, selector: "c8y-charts", inputs: ["config", "alerts", "chartViewContext"], outputs: ["configChangeOnZoomOut", "timeRangeChangeOnRealtime", "datapointOutOfSync", "datapointBackInSync", "updateAlarmsAndEvents", "isMarkedAreaEnabled", "finishLoading", "updateActiveDatapoints", "updateAggregatedSliderDatapoint", "duplicateAggregationsDetected"] }, { kind: "ngmodule", type: DatapointSelectorModule }, { kind: "ngmodule", type: AlarmEventSelectorModule }, { kind: "component", type: LocalControlsComponent, selector: "c8y-local-controls", inputs: ["controls", "displayMode", "config", "isLoading", "disabled", "propagateAutoRefresh", "emitRefresh", "dashboardChild"], outputs: ["configChange", "refresh"] }, { kind: "pipe", type: i1.C8yTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
235
+ ], viewQueries: [{ propertyName: "previewMapSet", first: true, predicate: ["dataPointsGraphPreview"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<form [formGroup]=\"formGroup\">\n <fieldset class=\"c8y-fieldset\">\n <legend>{{ 'Formatting' | translate }}</legend>\n <c8y-form-group class=\"form-group-sm\">\n <label\n [title]=\"'Number of decimal places' | translate\"\n translate\n >\n Number of decimal places\n </label>\n <input\n class=\"form-control\"\n name=\"numberOfDecimalPlaces\"\n type=\"number\"\n formControlName=\"numberOfDecimalPlaces\"\n [placeholder]=\"'e.g. {{ example }}' | translate: { example: 1 }\"\n />\n <c8y-messages\n [show]=\"\n formGroup.controls?.numberOfDecimalPlaces?.touched &&\n formGroup?.controls?.numberOfDecimalPlaces?.errors\n \"\n ></c8y-messages>\n </c8y-form-group>\n <c8y-form-group class=\"form-group-sm\">\n <label>\n {{ 'Data point legend display' | translate }}\n </label>\n <div\n class=\"c8y-select-wrapper\"\n [formGroup]=\"formGroup\"\n >\n <select\n class=\"form-control\"\n [title]=\"'Data point legend display' | translate\"\n id=\"dataPointLegendDisplay\"\n formControlName=\"dataPointLegendDisplay\"\n >\n @for (option of legendDisplayOptions; track option) {\n <option [ngValue]=\"option.value\">\n {{ option.label | translate }}\n </option>\n }\n </select>\n </div>\n </c8y-form-group>\n </fieldset>\n\n <fieldset class=\"c8y-fieldset\">\n <legend>{{ 'Display options' | translate }}</legend>\n <fieldset class=\"c8y-fieldset\">\n <legend>{{ 'Axis' | translate }}</legend>\n <c8y-form-group class=\"m-b-8 form-group-sm\">\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Y-axis helper lines' | translate\"\n >\n <input\n name=\"yAxisSplitLines\"\n type=\"checkbox\"\n formControlName=\"yAxisSplitLines\"\n />\n <span></span>\n <span translate>Y-axis helper lines</span>\n </label>\n <label\n class=\"c8y-checkbox\"\n [title]=\"'X-axis helper lines' | translate\"\n >\n <input\n name=\"xAxisSplitLines\"\n type=\"checkbox\"\n formControlName=\"xAxisSplitLines\"\n />\n <span></span>\n <span translate>X-axis helper lines</span>\n </label>\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Merge matching data points into a single axis' | translate\"\n >\n <input\n name=\"mergeMatchingDatapoints\"\n type=\"checkbox\"\n formControlName=\"mergeMatchingDatapoints\"\n />\n <span></span>\n <span translate>Merge matching data points into a single axis</span>\n <button\n class=\"btn-help\"\n [attr.aria-label]=\"\n 'Data points with the same min and max values will be merged into a single axis. The values must be defined in the data point configuration.'\n | translate\n \"\n [popover]=\"\n 'Data points with the same min and max values will be merged into a single axis. The values must be defined in the data point configuration.'\n | translate\n \"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n (click)=\"$event.stopPropagation()\"\n [adaptivePosition]=\"false\"\n ></button>\n </label>\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Force merge all data points into a single axis' | translate\"\n >\n <input\n name=\"forceMergeDatapoints\"\n type=\"checkbox\"\n formControlName=\"forceMergeDatapoints\"\n />\n <span></span>\n <span translate>Force merge all data points into a single axis</span>\n <button\n class=\"btn-help\"\n [attr.aria-label]=\"\n 'All axes will be force merged to a single axis with the scale being set to the max and min value of all axes. It\\'s recommended to use this option for data points with similar values.'\n | translate\n \"\n [popover]=\"\n 'All axes will be force merged to a single axis with the scale being set to the max and min value of all axes. It\\'s recommended to use this option for data points with similar values.'\n | translate\n \"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n (click)=\"$event.stopPropagation()\"\n [adaptivePosition]=\"false\"\n ></button>\n </label>\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Set Y-axis start to 0' | translate\"\n >\n <input\n name=\"setYaxisStartToZero\"\n type=\"checkbox\"\n formControlName=\"setYaxisStartToZero\"\n />\n <span></span>\n <span translate>Set Y-axis start to 0</span>\n <button\n class=\"btn-help\"\n [attr.aria-label]=\"\n 'Sets the Y-axis minimum to 0 for all data points with positive values. If any data point includes negative values, the axis may still extend below 0. Explicitly configured minimum and maximum values take precedence over this option.'\n | translate\n \"\n [popover]=\"\n 'Sets the Y-axis minimum to 0 for all data points with positive values. If any data point includes negative values, the axis may still extend below 0. Explicitly configured minimum and maximum values take precedence over this option.'\n | translate\n \"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n (click)=\"$event.stopPropagation()\"\n [adaptivePosition]=\"false\"\n ></button>\n </label>\n </c8y-form-group>\n </fieldset>\n <fieldset class=\"c8y-fieldset\">\n <legend>{{ 'Alarms & events' | translate }}</legend>\n <c8y-form-group class=\"m-b-8 form-group-sm\">\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Show vertical line on every occurrence' | translate\"\n >\n <input\n name=\"displayMarkedLine\"\n type=\"checkbox\"\n formControlName=\"displayMarkedLine\"\n />\n <span></span>\n <span translate>Show vertical line on every occurrence</span>\n </label>\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Show icon when triggered' | translate\"\n >\n <input\n name=\"displayMarkedPoint\"\n type=\"checkbox\"\n formControlName=\"displayMarkedPoint\"\n />\n <span></span>\n <span translate>Show icon when triggered</span>\n @if (alarmsOrEventsHaveNoMatchingDps) {\n <button\n class=\"btn-clean m-l-8\"\n [attr.aria-label]=\"\n 'Some alarms or events have no matching data points. No icons will be shown for them.'\n | translate\n \"\n [tooltip]=\"\n 'Some alarms or events have no matching data points. No icons will be shown for them.'\n | translate\n \"\n container=\"body\"\n type=\"button\"\n (click)=\"$event.stopPropagation()\"\n [adaptivePosition]=\"false\"\n >\n <i\n class=\"text-warning\"\n c8yIcon=\"exclamation-triangle\"\n ></i>\n </button>\n }\n </label>\n </c8y-form-group>\n </fieldset>\n <fieldset class=\"c8y-fieldset\">\n <legend>{{ 'Chart' | translate }}</legend>\n <c8y-form-group class=\"m-b-8 form-group-sm\">\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Show labels and units' | translate\"\n >\n <input\n name=\"showLabelAndUnit\"\n type=\"checkbox\"\n formControlName=\"showLabelAndUnit\"\n />\n <span></span>\n <span translate>Display labels and units on Y-axis</span>\n </label>\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Show slider' | translate\"\n >\n <input\n name=\"showSlider\"\n type=\"checkbox\"\n formControlName=\"showSlider\"\n />\n <span></span>\n <span translate>Show slider</span>\n </label>\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Show smooth lines' | translate\"\n >\n <input\n name=\"smoothLines\"\n type=\"checkbox\"\n formControlName=\"smoothLines\"\n />\n <span></span>\n <span translate>Show smooth lines</span>\n </label>\n </c8y-form-group>\n </fieldset>\n </fieldset>\n</form>\n\n<ng-template #dataPointsGraphPreview>\n @if (config?.displayMode && config.displayMode !== 'dashboard') {\n <c8y-local-controls\n [controls]=\"widgetControls\"\n [displayMode]=\"config.displayMode\"\n [config]=\"previewContextConfig()\"\n [disabled]=\"true\"\n ></c8y-local-controls>\n }\n\n @if (activeDatapointsExists) {\n <c8y-charts\n class=\"d-block p-relative\"\n [config]=\"config\"\n [alerts]=\"alerts\"\n [chartViewContext]=\"chartViewContext\"\n (timeRangeChangeOnRealtime)=\"updateTimeRangeOnRealtime($event)\"\n (configChangeOnZoomOut)=\"updateDashboardTimeContext($event)\"\n (updateAggregatedSliderDatapoint)=\"updateAggregatedSliderDatapoint($event)\"\n ></c8y-charts>\n }\n\n @if (!activeDatapointsExists) {\n <c8y-ui-empty-state\n class=\"d-block m-t-24\"\n [icon]=\"'search'\"\n [title]=\"'No data points selected' | translate\"\n [subtitle]=\"'Select data point to render content' | translate\"\n data-cy=\"datapoints-graph-list--empty-state-no-data-point-selected\"\n >\n <p c8y-guide-docs>\n <small\n translate\n ngNonBindable\n >\n Find out more in the\n <a c8y-guide-href=\"/docs/cockpit/widgets-collection/#data-point-graph\">\n user documentation</a\n >.\n </small>\n </p>\n </c8y-ui-empty-state>\n }\n</ng-template>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: i1.EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "directive", type: i1.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i1.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "ngmodule", type: CoreModule }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "component", type: i1.FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "component", type: i1.MessagesComponent, selector: "c8y-messages", inputs: ["show", "defaults", "helpMessage", "additionalMessages"] }, { kind: "directive", type: i1.RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "directive", type: i1.GuideHrefDirective, selector: "[c8y-guide-href]", inputs: ["c8y-guide-href"] }, { kind: "component", type: i1.GuideDocsComponent, selector: "[c8y-guide-docs]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i3.TooltipDirective, selector: "[tooltip], [tooltipHtml]", inputs: ["adaptivePosition", "tooltip", "placement", "triggers", "container", "containerClass", "boundariesElement", "isOpen", "isDisabled", "delay", "tooltipHtml", "tooltipPlacement", "tooltipIsOpen", "tooltipEnable", "tooltipAppendToBody", "tooltipAnimation", "tooltipClass", "tooltipContext", "tooltipPopupDelay", "tooltipFadeDuration", "tooltipTrigger"], outputs: ["tooltipChange", "onShown", "onHidden", "tooltipStateChanged"], exportAs: ["bs-tooltip"] }, { kind: "ngmodule", type: PopoverModule }, { kind: "directive", type: i4.PopoverDirective, selector: "[popover]", inputs: ["adaptivePosition", "boundariesElement", "popover", "popoverContext", "popoverTitle", "placement", "outsideClick", "triggers", "container", "containerClass", "isOpen", "delay"], outputs: ["onShown", "onHidden"], exportAs: ["bs-popover"] }, { kind: "component", type: ChartsComponent, selector: "c8y-charts", inputs: ["config", "alerts", "chartViewContext"], outputs: ["configChangeOnZoomOut", "timeRangeChangeOnRealtime", "datapointOutOfSync", "datapointBackInSync", "updateAlarmsAndEvents", "isMarkedAreaEnabled", "finishLoading", "updateActiveDatapoints", "selectedChange", "updateAggregatedSliderDatapoint", "duplicateAggregationsDetected"] }, { kind: "ngmodule", type: DatapointSelectorModule }, { kind: "ngmodule", type: AlarmEventSelectorModule }, { kind: "component", type: LocalControlsComponent, selector: "c8y-local-controls", inputs: ["controls", "displayMode", "config", "isLoading", "disabled", "propagateAutoRefresh", "emitRefresh", "dashboardChild"], outputs: ["configChange", "refresh"] }, { kind: "pipe", type: i1.C8yTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
236
236
  }
237
237
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: DatapointsGraphWidgetConfigComponent, decorators: [{
238
238
  type: Component,
@@ -265,6 +265,9 @@ class DatapointsGraphWidgetViewComponent {
265
265
  // This is needed to reflect migrated states in the widget config.
266
266
  const migratedConfig = this.widgetConfigMigrationService.migrateWidgetConfig(value);
267
267
  const newConfig = merge(value, migratedConfig);
268
+ // Keep the original input reference so the clicked data point can be mirrored
269
+ // back onto it.
270
+ this.originalConfig = value;
268
271
  this.displayConfig = cloneDeep(newConfig);
269
272
  }
270
273
  get config() {
@@ -368,6 +371,18 @@ class DatapointsGraphWidgetViewComponent {
368
371
  this.contextConfig.set(initialContextConfig);
369
372
  this.updateExportConfig();
370
373
  }
374
+ /**
375
+ * Mirrors the data point clicked on the chart back onto the original widget config
376
+ * so `config.selected` stays observable from outside the widget.
377
+ */
378
+ onSelectedChange(selected) {
379
+ if (this.originalConfig) {
380
+ this.originalConfig.selected = selected;
381
+ }
382
+ if (this.displayConfig) {
383
+ this.displayConfig.selected = selected;
384
+ }
385
+ }
371
386
  onContextChange(event) {
372
387
  this.invalidateHiddenItemsCache();
373
388
  this.contextConfig.set(event.context);
@@ -909,7 +924,7 @@ class DatapointsGraphWidgetViewComponent {
909
924
  return source?.refreshOption === REFRESH_OPTION.LIVE && !!source?.isAutoRefreshEnabled;
910
925
  }
911
926
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: DatapointsGraphWidgetViewComponent, deps: [{ token: i1$1.TranslateService }, { token: i2$1.ContextDashboardComponent, optional: true }, { token: i3$1.WidgetConfigMigrationService }, { token: i1.WidgetTimeContextDateRangeService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
912
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.19", type: DatapointsGraphWidgetViewComponent, isStandalone: true, selector: "c8y-datapoints-graph-widget-view", inputs: { config: "config" }, providers: [ChartEventsService, ChartAlarmsService, WidgetTimeContextDateRangeService], viewQueries: [{ propertyName: "chartComponent", first: true, predicate: ChartsComponent, descendants: true }], ngImport: i0, template: "@if (displayMode() === GLOBAL_CONTEXT_DISPLAY_MODE.DASHBOARD) {\n <c8y-global-context-connector\n [controls]=\"widgetControls()\"\n [config]=\"contextConfig()\"\n [isLoading]=\"isLoading$ | async\"\n [dashboardChild]=\"getDashboardChild()\"\n [linked]=\"isLinkedToGlobal()\"\n [propagateAutoRefresh]=\"false\"\n (configChange)=\"onContextChange($event)\"\n ></c8y-global-context-connector>\n} @else {\n <c8y-local-controls\n [controls]=\"widgetControls()\"\n [displayMode]=\"displayMode()\"\n [config]=\"contextConfig()\"\n [isLoading]=\"isLoading$ | async\"\n [propagateAutoRefresh]=\"false\"\n (configChange)=\"onContextChange($event)\"\n ></c8y-local-controls>\n}\n\n<div\n class=\"p-l-16 p-r-16\"\n style=\"min-height: 34px\"\n>\n <div class=\"d-flex gap-16 a-i-center\">\n @if (hasAtLeastOneAlarmActive) {\n <c8y-alarms-filter\n class=\"d-contents form-group-sm min-width-0\"\n (onFilterApplied)=\"filterSeverity($event)\"\n ></c8y-alarms-filter>\n }\n @if (displayConfig?.datapoints.length > 0) {\n <div class=\"d-flex a-i-center min-width-0\">\n @if (\n displayConfig.dataPointLegendDisplay === 'dropdown' ||\n (displayConfig.dataPointLegendDisplay === 'auto' && totalLegendItems > 5)\n ) {\n <c8y-select\n class=\"min-width-0 c8y-select-v2--sm\"\n aria-label=\"{{ 'Select data points, alarms or events' | translate }}\"\n [placeholder]=\"'Select data points, alarms or events' | translate\"\n [multi]=\"true\"\n [filterItems]=\"true\"\n [(ngModel)]=\"selectedItems\"\n (onSelect)=\"onItemSelected($event)\"\n (onDeselect)=\"onItemDeselected($event)\"\n >\n @for (item of selectableItems; track item.value) {\n @let isDuplicate = isDuplicateDropdownItem(item);\n <div\n class=\"d-flex a-i-center gap-4\"\n [style.opacity]=\"isDuplicate ? '0.5' : null\"\n *c8ySelectItem=\"item.value; label: item.label\"\n >\n @if (\n !hasAtLeastOneDatapointActive &&\n item.value.type === 'DATAPOINT' &&\n (!item.value.renderTypeFn\n ? item.value.original.__active\n : isRenderTypeFunctionVisible(\n $any(item.value.original),\n item.value.renderTypeFn\n ))\n ) {\n <i\n class=\"text-warning m-r-4\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"'At least 1 data point must be active.' | translate\"\n container=\"body\"\n data-cy=\"datapoint-warning-icon\"\n [adaptivePosition]=\"false\"\n ></i>\n }\n @if (isDuplicate) {\n <i\n class=\"text-warning m-r-4\"\n c8yIcon=\"warning2\"\n [tooltip]=\"duplicateAggrWarning\"\n container=\"body\"\n [adaptivePosition]=\"false\"\n ></i>\n }\n @if (item.value.type === 'DATAPOINT') {\n @let fnColor =\n item.value.renderTypeFn\n ? $any(item.value.original).renderTypeColors?.[item.value.renderTypeFn] ||\n item.value.original.color\n : item.value.original.color;\n <span\n class=\"circle-icon-wrapper a-s-start circle-icon-wrapper--small\"\n [style.background-color]=\"fnColor\"\n ></span>\n }\n @if (item.value.type === 'ALARM') {\n <span\n class=\"circle-icon-wrapper a-s-start circle-icon-wrapper--small\"\n [style.background-color]=\"item.value.original.color\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"bell\"\n ></i>\n </span>\n }\n @if (item.value.type === 'EVENT') {\n <span\n class=\"circle-icon-wrapper a-s-start circle-icon-wrapper--small\"\n [ngStyle]=\"{ 'background-color': item.value.original.color }\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"online1\"\n ></i>\n </span>\n }\n <span class=\"text-truncate d-col\">\n <small class=\"text-truncate\">{{ item.label }}</small>\n <span class=\"text-muted text-10\">{{ item.value.original.__target?.name }}</span>\n </span>\n </div>\n }\n <span\n class=\"tag tag--info chip\"\n [style.opacity]=\"isDuplicateDropdownItem(selectedItem) ? '0.6' : null\"\n title=\"{{ selectedItem.label }}\"\n *c8ySelectedItems=\"let selectedItem\"\n >\n @let isDuplicateChip = isDuplicateDropdownItem(selectedItem);\n <button\n class=\"btn btn-xs btn-clean text-10\"\n title=\"{{ selectedItem.label }}\"\n type=\"button\"\n (click)=\"\n $event.preventDefault(); $event.stopPropagation(); onItemDeselected(selectedItem)\n \"\n >\n <i c8yIcon=\"times\"></i>\n </button>\n @if (isLastActiveDatapoint(selectedItem)) {\n <i\n class=\"text-warning a-s-start\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"'At least 1 data point must be active.' | translate\"\n container=\"body\"\n data-cy=\"datapoint-warning-icon\"\n [adaptivePosition]=\"false\"\n ></i>\n }\n @if (isDuplicateChip) {\n <i\n class=\"text-warning a-s-start\"\n c8yIcon=\"warning2\"\n [tooltip]=\"duplicateAggrWarning\"\n container=\"body\"\n [adaptivePosition]=\"false\"\n ></i>\n }\n @if (selectedItem.value.type === 'DATAPOINT') {\n @let fnColor =\n selectedItem.value.renderTypeFn\n ? $any(selectedItem.value.original).renderTypeColors?.[\n selectedItem.value.renderTypeFn\n ] || selectedItem.value.original.color\n : selectedItem.value?.original.color || '';\n <span\n class=\"circle-icon-wrapper circle-icon-wrapper--small\"\n [style.background-color]=\"fnColor\"\n ></span>\n }\n @if (selectedItem.value?.type === 'ALARM') {\n <span\n class=\"circle-icon-wrapper circle-icon-wrapper--small\"\n [style.background-color]=\"selectedItem.value?.original.color || ''\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"bell\"\n ></i>\n </span>\n }\n @if (selectedItem.value?.type === 'EVENT') {\n <span\n class=\"circle-icon-wrapper circle-icon-wrapper--small\"\n [ngStyle]=\"{\n 'background-color': selectedItem.value?.original.color || ''\n }\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"online1\"\n ></i>\n </span>\n }\n </span>\n </c8y-select>\n } @else {\n <div class=\"inner-scroll\">\n <div class=\"p-t-4 d-flex a-i-start gap-8\">\n @for (datapoint of displayConfig.datapoints; track datapoint) {\n @let rtColors = getAggregationFunctionColors(datapoint);\n @let dpId = getDpId(datapoint);\n @if (datapoint.retrievalError) {\n <i\n class=\"text-warning m-l-4\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"'Data point no longer exists.' | translate\"\n container=\"body\"\n [adaptivePosition]=\"false\"\n ></i>\n } @else if (\n rtColors.length > 0 &&\n datapointsWithDuplicateAggr.has(dpId) &&\n displayConfig?.aggregation\n ) {\n <!-- All aggregation functions return the same value \u2014 collapse to a single muted pill -->\n <div\n class=\"c8y-datapoint-pill pill--sm flex-no-shrink\"\n [class.active]=\"datapoint.__active\"\n style=\"opacity: 0.5\"\n title=\"{{ datapoint.label }} - {{ datapoint.__target.name }}\"\n >\n <button\n class=\"c8y-datapoint-pill__btn\"\n title=\"{{\n (datapoint.__active ? hideDatapointLabel : showDatapointLabel) | translate\n }}\"\n type=\"button\"\n data-cy=\"datapoint-toggle-visibility-btn\"\n (click)=\"toggleChart(datapoint)\"\n >\n <i\n class=\"icon-14\"\n [c8yIcon]=\"datapoint.__active ? 'eye text-primary' : 'eye-slash text-muted'\"\n ></i>\n </button>\n <div class=\"c8y-datapoint-pill__label c8y-datapoint-pill__btn\">\n <i\n class=\"m-r-4 icon-14\"\n c8yIcon=\"circle\"\n [style.color]=\"datapoint.color\"\n ></i>\n <span\n class=\"text-truncate\"\n [class.text-muted]=\"!datapoint.__active\"\n >\n <span class=\"text-truncate text-bold\">{{ datapoint.label }}</span>\n <small class=\"text-muted text-10\">{{ datapoint.__target.name }}</small>\n </span>\n <i\n class=\"text-warning m-l-4\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"duplicateAggrWarning\"\n container=\"body\"\n [adaptivePosition]=\"false\"\n ></i>\n </div>\n </div>\n } @else if (rtColors.length > 0) {\n @for (entry of rtColors; track entry.renderType) {\n @let isVisible = isRenderTypeFunctionVisible(datapoint, entry.renderType);\n <div\n class=\"c8y-datapoint-pill pill--sm flex-no-shrink\"\n [class.active]=\"isVisible\"\n title=\"{{ datapoint.label }} [{{ entry.renderType }}] - {{\n datapoint.__target.name\n }}\"\n >\n @if (!hasAtLeastOneDatapointActive && isVisible) {\n <i\n class=\"text-warning m-l-4\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"'At least 1 data point must be active.' | translate\"\n container=\"body\"\n data-cy=\"datapoint-warning-icon\"\n [adaptivePosition]=\"false\"\n ></i>\n }\n <button\n class=\"c8y-datapoint-pill__btn\"\n title=\"{{\n (isVisible ? hideDatapointLabel : showDatapointLabel) | translate\n }}\"\n type=\"button\"\n data-cy=\"datapoint-toggle-visibility-btn\"\n (click)=\"toggleRenderTypeFunction(datapoint, entry.renderType, !isVisible)\"\n >\n <i\n class=\"icon-14\"\n [c8yIcon]=\"isVisible ? 'eye text-primary' : 'eye-slash text-muted'\"\n ></i>\n </button>\n <div class=\"c8y-datapoint-pill__label c8y-datapoint-pill__btn\">\n <i\n class=\"m-r-4 icon-14\"\n c8yIcon=\"circle\"\n [style.color]=\"entry.color\"\n ></i>\n <span\n class=\"text-truncate\"\n [class.text-muted]=\"!isVisible\"\n >\n <span class=\"text-truncate text-bold\">\n {{ datapoint.label }} [{{ entry.renderType }}]\n </span>\n <small class=\"text-muted text-10\">\n {{ datapoint.__target.name }}\n </small>\n </span>\n </div>\n </div>\n }\n } @else {\n <div\n class=\"c8y-datapoint-pill pill--sm flex-no-shrink\"\n title=\"{{ datapoint.label }} - {{ datapoint.__target.name }}\"\n [ngClass]=\"{ active: datapoint.__active }\"\n >\n @if (!hasAtLeastOneDatapointActive && datapoint.__active) {\n <i\n class=\"text-warning m-l-4\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"'At least 1 data point must be active.' | translate\"\n container=\"body\"\n data-cy=\"datapoint-warning-icon\"\n [adaptivePosition]=\"false\"\n ></i>\n }\n <button\n class=\"c8y-datapoint-pill__btn\"\n title=\"{{\n (datapoint.__active ? hideDatapointLabel : showDatapointLabel) | translate\n }} \"\n type=\"button\"\n data-cy=\"datapoint-toggle-visibility-btn\"\n (click)=\"toggleChart(datapoint)\"\n >\n <i\n class=\"icon-14\"\n [c8yIcon]=\"datapoint.__active ? 'eye text-primary' : 'eye-slash text-muted'\"\n ></i>\n </button>\n <div class=\"c8y-datapoint-pill__label c8y-datapoint-pill__btn\">\n <i\n class=\"m-r-4 icon-14\"\n c8yIcon=\"circle\"\n [ngStyle]=\"{\n color: datapoint.color\n }\"\n ></i>\n <span\n class=\"text-truncate\"\n [ngClass]=\"{ 'text-muted': !datapoint.__active }\"\n >\n <span class=\"text-truncate text-bold\">\n {{ datapoint.label }}\n </span>\n <small class=\"text-muted text-10\">\n {{ datapoint.__target.name }}\n </small>\n </span>\n @if (datapointsOutOfSync.get(datapoint)) {\n <i\n class=\"text-warning m-l-4\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"\n 'Measurements received for this data point may be out of sync.'\n | translate\n \"\n container=\"body\"\n [adaptivePosition]=\"false\"\n ></i>\n }\n </div>\n </div>\n }\n }\n\n @for (alarm of alarms; track alarm) {\n <div\n class=\"c8y-alarm-pill pill--sm flex-no-shrink\"\n title=\"{{ alarm.filters.type }} \"\n >\n @if (displayConfig?.activeAlarmTypesOutOfRange?.includes(alarm.filters.type)) {\n <i\n class=\"text-warning m-l-4\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"\n 'Alarm of this type is currently active and outside of the selected time range'\n | translate\n \"\n container=\"body\"\n [adaptivePosition]=\"false\"\n ></i>\n }\n <button\n class=\"c8y-alarm-pill__btn\"\n title=\"{{ alarm.filters.type }} \"\n type=\"button\"\n (click)=\"toggleAlarmEventType(alarm)\"\n >\n <i\n class=\"icon-14\"\n [c8yIcon]=\"\n alarm.__hidden || !alarm.__active\n ? 'eye-slash text-muted'\n : 'eye text-primary'\n \"\n ></i>\n </button>\n <button\n class=\"c8y-alarm-pill__label c8y-alarm-pill__btn\"\n (click)=\"toggleMarkedArea(alarm)\"\n [ngClass]=\"{\n active:\n !isMarkedAreaEnabled && alarm.filters.type === enabledMarkedAreaAlarmType\n }\"\n >\n <span\n class=\"circle-icon-wrapper circle-icon-wrapper--small m-r-4\"\n [style.background-color]=\"alarm.color\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"bell\"\n ></i>\n </span>\n <span\n class=\"text-truncate\"\n [ngClass]=\"{ 'text-muted': alarm.__hidden }\"\n >\n <span class=\"text-truncate text-bold\">\n {{ alarm.label || alarm.filters.type }}\n </span>\n <small class=\"text-muted text-10\">\n {{ alarm.__target.name }}\n </small>\n </span>\n </button>\n </div>\n }\n\n @for (event of events; track event) {\n <div\n class=\"c8y-event-pill pill--sm flex-no-shrink\"\n title=\"{{ event.filters.type }}\"\n >\n <button\n class=\"c8y-event-pill__btn\"\n title=\"{{ event.filters.type }} \"\n type=\"button\"\n (click)=\"toggleAlarmEventType(event)\"\n >\n <i\n class=\"icon-14\"\n [c8yIcon]=\"\n event.__hidden || !event.__active\n ? 'eye-slash text-muted'\n : 'eye text-primary'\n \"\n ></i>\n </button>\n <div class=\"c8y-event-pill__label c8y-event-pill__btn\">\n <span\n class=\"circle-icon-wrapper circle-icon-wrapper--small m-r-4\"\n [ngStyle]=\"{ 'background-color': event.color }\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"online1\"\n ></i>\n </span>\n <span\n class=\"text-truncate text-bold\"\n [ngClass]=\"{ 'text-muted': event.__hidden }\"\n >\n <span class=\"text-truncate\">\n {{ event.label || event.filters.type }}\n </span>\n <small class=\"text-muted text-10\">\n {{ event.__target.name }}\n </small>\n </span>\n </div>\n </div>\n }\n </div>\n </div>\n <button\n class=\"btn-help btn-help--sm m-r-8\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"legendHelpTemplate\"\n placement=\"left\"\n triggers=\"focus\"\n container=\"body\"\n [adaptivePosition]=\"true\"\n ></button>\n }\n </div>\n }\n </div>\n</div>\n\n@if (displayConfig !== null) {\n <c8y-charts\n #chart\n [config]=\"displayConfig\"\n [alerts]=\"alerts\"\n [chartViewContext]=\"chartViewContext\"\n (updateAlarmsAndEvents)=\"updateAlarmsAndEvents($event)\"\n (configChangeOnZoomOut)=\"updateDashboardTimeContext($event)\"\n (datapointOutOfSync)=\"handleDatapointOutOfSync($event)\"\n (datapointBackInSync)=\"handleDatapointBackInSync($event)\"\n (finishLoading)=\"this.isLoading$.next($event)\"\n (isMarkedAreaEnabled)=\"isMarkedAreaEnabled = $event\"\n (duplicateAggregationsDetected)=\"onDuplicateAggregationsDetected($event)\"\n ></c8y-charts>\n}\n\n<ng-template #legendHelpTemplate>\n <div [innerHTML]=\"legendHelp\"></div>\n</ng-template>\n\n<c8y-widget-action>\n <c8y-datapoints-export-selector\n [displayMode]=\"'icon-only'\"\n [exportConfig]=\"exportConfig\"\n [containerClass]=\"'d-contents'\"\n ></c8y-datapoints-export-selector>\n <button\n class=\"btn btn-icon\"\n [attr.aria-label]=\"'Save as image' | translate\"\n tooltip=\"{{ 'Save as image' | translate }}\"\n container=\"body\"\n type=\"button\"\n [delay]=\"500\"\n (click)=\"chartComponent.saveAsImage()\"\n [adaptivePosition]=\"false\"\n >\n <i\n class=\"icon-14\"\n c8yIcon=\"image-file-checked\"\n ></i>\n </button>\n</c8y-widget-action>\n", dependencies: [{ kind: "ngmodule", type: A11yModule }, { kind: "ngmodule", type: CommonModule$1 }, { kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: ChartsComponent, selector: "c8y-charts", inputs: ["config", "alerts", "chartViewContext"], outputs: ["configChangeOnZoomOut", "timeRangeChangeOnRealtime", "datapointOutOfSync", "datapointBackInSync", "updateAlarmsAndEvents", "isMarkedAreaEnabled", "finishLoading", "updateActiveDatapoints", "updateAggregatedSliderDatapoint", "duplicateAggregationsDetected"] }, { kind: "ngmodule", type: CoreModule }, { kind: "directive", type: i1.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "component", type: i1.SelectComponent, selector: "c8y-select", inputs: ["placeholder", "items", "selected", "container", "multi", "canSelectWithSpace", "disabled", "autoClose", "insideClick", "required", "canDeselect", "name", "icon", "filterItems"], outputs: ["onSelect", "onDeselect", "onIconClick"] }, { kind: "directive", type: i1.SelectItemDirective, selector: "[c8ySelectItem]", inputs: ["c8ySelectItem", "c8ySelectItemLabel"] }, { kind: "directive", type: i1.SelectedItemsDirective, selector: "[c8ySelectedItems]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i3.TooltipDirective, selector: "[tooltip], [tooltipHtml]", inputs: ["adaptivePosition", "tooltip", "placement", "triggers", "container", "containerClass", "boundariesElement", "isOpen", "isDisabled", "delay", "tooltipHtml", "tooltipPlacement", "tooltipIsOpen", "tooltipEnable", "tooltipAppendToBody", "tooltipAnimation", "tooltipClass", "tooltipContext", "tooltipPopupDelay", "tooltipFadeDuration", "tooltipTrigger"], outputs: ["tooltipChange", "onShown", "onHidden", "tooltipStateChanged"], exportAs: ["bs-tooltip"] }, { kind: "ngmodule", type: BsDropdownModule }, { kind: "ngmodule", type: PopoverModule }, { kind: "directive", type: i4.PopoverDirective, selector: "[popover]", inputs: ["adaptivePosition", "boundariesElement", "popover", "popoverContext", "popoverTitle", "placement", "outsideClick", "triggers", "container", "containerClass", "isOpen", "delay"], outputs: ["onShown", "onHidden"], exportAs: ["bs-popover"] }, { kind: "ngmodule", type: AlarmsModule }, { kind: "component", type: i9.AlarmsFilterComponent, selector: "c8y-alarms-filter", inputs: ["contextSourceId"], outputs: ["onFilterApplied"] }, { kind: "component", type: GlobalContextConnectorComponent, selector: "c8y-global-context-connector", inputs: ["controls", "config", "isLoading", "dashboardChild", "linked", "propagateAutoRefresh", "emitRefresh"], outputs: ["configChange", "refresh", "linkedChange"] }, { kind: "component", type: LocalControlsComponent, selector: "c8y-local-controls", inputs: ["controls", "displayMode", "config", "isLoading", "disabled", "propagateAutoRefresh", "emitRefresh", "dashboardChild"], outputs: ["configChange", "refresh"] }, { kind: "component", type: DatapointsExportSelectorComponent, selector: "c8y-datapoints-export-selector", inputs: ["displayMode", "containerClass", "exportConfig"], outputs: ["isOpen"] }, { kind: "component", type: WidgetActionWrapperComponent, selector: "c8y-widget-action" }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }, { kind: "pipe", type: i1.C8yTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
927
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.19", type: DatapointsGraphWidgetViewComponent, isStandalone: true, selector: "c8y-datapoints-graph-widget-view", inputs: { config: "config" }, providers: [ChartEventsService, ChartAlarmsService, WidgetTimeContextDateRangeService], viewQueries: [{ propertyName: "chartComponent", first: true, predicate: ChartsComponent, descendants: true }], ngImport: i0, template: "@if (displayMode() === GLOBAL_CONTEXT_DISPLAY_MODE.DASHBOARD) {\n <c8y-global-context-connector\n [controls]=\"widgetControls()\"\n [config]=\"contextConfig()\"\n [isLoading]=\"isLoading$ | async\"\n [dashboardChild]=\"getDashboardChild()\"\n [linked]=\"isLinkedToGlobal()\"\n [propagateAutoRefresh]=\"false\"\n (configChange)=\"onContextChange($event)\"\n ></c8y-global-context-connector>\n} @else {\n <c8y-local-controls\n [controls]=\"widgetControls()\"\n [displayMode]=\"displayMode()\"\n [config]=\"contextConfig()\"\n [isLoading]=\"isLoading$ | async\"\n [propagateAutoRefresh]=\"false\"\n (configChange)=\"onContextChange($event)\"\n ></c8y-local-controls>\n}\n\n<div\n class=\"p-l-16 p-r-16\"\n style=\"min-height: 34px\"\n>\n <div class=\"d-flex gap-16 a-i-center\">\n @if (hasAtLeastOneAlarmActive) {\n <c8y-alarms-filter\n class=\"d-contents form-group-sm min-width-0\"\n (onFilterApplied)=\"filterSeverity($event)\"\n ></c8y-alarms-filter>\n }\n @if (displayConfig?.datapoints.length > 0) {\n <div class=\"d-flex a-i-center min-width-0\">\n @if (\n displayConfig.dataPointLegendDisplay === 'dropdown' ||\n (displayConfig.dataPointLegendDisplay === 'auto' && totalLegendItems > 5)\n ) {\n <c8y-select\n class=\"min-width-0 c8y-select-v2--sm\"\n aria-label=\"{{ 'Select data points, alarms or events' | translate }}\"\n [placeholder]=\"'Select data points, alarms or events' | translate\"\n [multi]=\"true\"\n [filterItems]=\"true\"\n [(ngModel)]=\"selectedItems\"\n (onSelect)=\"onItemSelected($event)\"\n (onDeselect)=\"onItemDeselected($event)\"\n >\n @for (item of selectableItems; track item.value) {\n @let isDuplicate = isDuplicateDropdownItem(item);\n <div\n class=\"d-flex a-i-center gap-4\"\n [style.opacity]=\"isDuplicate ? '0.5' : null\"\n *c8ySelectItem=\"item.value; label: item.label\"\n >\n @if (\n !hasAtLeastOneDatapointActive &&\n item.value.type === 'DATAPOINT' &&\n (!item.value.renderTypeFn\n ? item.value.original.__active\n : isRenderTypeFunctionVisible(\n $any(item.value.original),\n item.value.renderTypeFn\n ))\n ) {\n <i\n class=\"text-warning m-r-4\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"'At least 1 data point must be active.' | translate\"\n container=\"body\"\n data-cy=\"datapoint-warning-icon\"\n [adaptivePosition]=\"false\"\n ></i>\n }\n @if (isDuplicate) {\n <i\n class=\"text-warning m-r-4\"\n c8yIcon=\"warning2\"\n [tooltip]=\"duplicateAggrWarning\"\n container=\"body\"\n [adaptivePosition]=\"false\"\n ></i>\n }\n @if (item.value.type === 'DATAPOINT') {\n @let fnColor =\n item.value.renderTypeFn\n ? $any(item.value.original).renderTypeColors?.[item.value.renderTypeFn] ||\n item.value.original.color\n : item.value.original.color;\n <span\n class=\"circle-icon-wrapper a-s-start circle-icon-wrapper--small\"\n [style.background-color]=\"fnColor\"\n ></span>\n }\n @if (item.value.type === 'ALARM') {\n <span\n class=\"circle-icon-wrapper a-s-start circle-icon-wrapper--small\"\n [style.background-color]=\"item.value.original.color\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"bell\"\n ></i>\n </span>\n }\n @if (item.value.type === 'EVENT') {\n <span\n class=\"circle-icon-wrapper a-s-start circle-icon-wrapper--small\"\n [ngStyle]=\"{ 'background-color': item.value.original.color }\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"online1\"\n ></i>\n </span>\n }\n <span class=\"text-truncate d-col\">\n <small class=\"text-truncate\">{{ item.label }}</small>\n <span class=\"text-muted text-10\">{{ item.value.original.__target?.name }}</span>\n </span>\n </div>\n }\n <span\n class=\"tag tag--info chip\"\n [style.opacity]=\"isDuplicateDropdownItem(selectedItem) ? '0.6' : null\"\n title=\"{{ selectedItem.label }}\"\n *c8ySelectedItems=\"let selectedItem\"\n >\n @let isDuplicateChip = isDuplicateDropdownItem(selectedItem);\n <button\n class=\"btn btn-xs btn-clean text-10\"\n title=\"{{ selectedItem.label }}\"\n type=\"button\"\n (click)=\"\n $event.preventDefault(); $event.stopPropagation(); onItemDeselected(selectedItem)\n \"\n >\n <i c8yIcon=\"times\"></i>\n </button>\n @if (isLastActiveDatapoint(selectedItem)) {\n <i\n class=\"text-warning a-s-start\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"'At least 1 data point must be active.' | translate\"\n container=\"body\"\n data-cy=\"datapoint-warning-icon\"\n [adaptivePosition]=\"false\"\n ></i>\n }\n @if (isDuplicateChip) {\n <i\n class=\"text-warning a-s-start\"\n c8yIcon=\"warning2\"\n [tooltip]=\"duplicateAggrWarning\"\n container=\"body\"\n [adaptivePosition]=\"false\"\n ></i>\n }\n @if (selectedItem.value.type === 'DATAPOINT') {\n @let fnColor =\n selectedItem.value.renderTypeFn\n ? $any(selectedItem.value.original).renderTypeColors?.[\n selectedItem.value.renderTypeFn\n ] || selectedItem.value.original.color\n : selectedItem.value?.original.color || '';\n <span\n class=\"circle-icon-wrapper circle-icon-wrapper--small\"\n [style.background-color]=\"fnColor\"\n ></span>\n }\n @if (selectedItem.value?.type === 'ALARM') {\n <span\n class=\"circle-icon-wrapper circle-icon-wrapper--small\"\n [style.background-color]=\"selectedItem.value?.original.color || ''\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"bell\"\n ></i>\n </span>\n }\n @if (selectedItem.value?.type === 'EVENT') {\n <span\n class=\"circle-icon-wrapper circle-icon-wrapper--small\"\n [ngStyle]=\"{\n 'background-color': selectedItem.value?.original.color || ''\n }\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"online1\"\n ></i>\n </span>\n }\n </span>\n </c8y-select>\n } @else {\n <div class=\"inner-scroll\">\n <div class=\"p-t-4 d-flex a-i-start gap-8\">\n @for (datapoint of displayConfig.datapoints; track datapoint) {\n @let rtColors = getAggregationFunctionColors(datapoint);\n @let dpId = getDpId(datapoint);\n @if (datapoint.retrievalError) {\n <i\n class=\"text-warning m-l-4\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"'Data point no longer exists.' | translate\"\n container=\"body\"\n [adaptivePosition]=\"false\"\n ></i>\n } @else if (\n rtColors.length > 0 &&\n datapointsWithDuplicateAggr.has(dpId) &&\n displayConfig?.aggregation\n ) {\n <!-- All aggregation functions return the same value \u2014 collapse to a single muted pill -->\n <div\n class=\"c8y-datapoint-pill pill--sm flex-no-shrink\"\n [class.active]=\"datapoint.__active\"\n style=\"opacity: 0.5\"\n title=\"{{ datapoint.label }} - {{ datapoint.__target.name }}\"\n >\n <button\n class=\"c8y-datapoint-pill__btn\"\n title=\"{{\n (datapoint.__active ? hideDatapointLabel : showDatapointLabel) | translate\n }}\"\n type=\"button\"\n data-cy=\"datapoint-toggle-visibility-btn\"\n (click)=\"toggleChart(datapoint)\"\n >\n <i\n class=\"icon-14\"\n [c8yIcon]=\"datapoint.__active ? 'eye text-primary' : 'eye-slash text-muted'\"\n ></i>\n </button>\n <div class=\"c8y-datapoint-pill__label c8y-datapoint-pill__btn\">\n <i\n class=\"m-r-4 icon-14\"\n c8yIcon=\"circle\"\n [style.color]=\"datapoint.color\"\n ></i>\n <span\n class=\"text-truncate\"\n [class.text-muted]=\"!datapoint.__active\"\n >\n <span class=\"text-truncate text-bold\">{{ datapoint.label }}</span>\n <small class=\"text-muted text-10\">{{ datapoint.__target.name }}</small>\n </span>\n <i\n class=\"text-warning m-l-4\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"duplicateAggrWarning\"\n container=\"body\"\n [adaptivePosition]=\"false\"\n ></i>\n </div>\n </div>\n } @else if (rtColors.length > 0) {\n @for (entry of rtColors; track entry.renderType) {\n @let isVisible = isRenderTypeFunctionVisible(datapoint, entry.renderType);\n <div\n class=\"c8y-datapoint-pill pill--sm flex-no-shrink\"\n [class.active]=\"isVisible\"\n title=\"{{ datapoint.label }} [{{ entry.renderType }}] - {{\n datapoint.__target.name\n }}\"\n >\n @if (!hasAtLeastOneDatapointActive && isVisible) {\n <i\n class=\"text-warning m-l-4\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"'At least 1 data point must be active.' | translate\"\n container=\"body\"\n data-cy=\"datapoint-warning-icon\"\n [adaptivePosition]=\"false\"\n ></i>\n }\n <button\n class=\"c8y-datapoint-pill__btn\"\n title=\"{{\n (isVisible ? hideDatapointLabel : showDatapointLabel) | translate\n }}\"\n type=\"button\"\n data-cy=\"datapoint-toggle-visibility-btn\"\n (click)=\"toggleRenderTypeFunction(datapoint, entry.renderType, !isVisible)\"\n >\n <i\n class=\"icon-14\"\n [c8yIcon]=\"isVisible ? 'eye text-primary' : 'eye-slash text-muted'\"\n ></i>\n </button>\n <div class=\"c8y-datapoint-pill__label c8y-datapoint-pill__btn\">\n <i\n class=\"m-r-4 icon-14\"\n c8yIcon=\"circle\"\n [style.color]=\"entry.color\"\n ></i>\n <span\n class=\"text-truncate\"\n [class.text-muted]=\"!isVisible\"\n >\n <span class=\"text-truncate text-bold\">\n {{ datapoint.label }} [{{ entry.renderType }}]\n </span>\n <small class=\"text-muted text-10\">\n {{ datapoint.__target.name }}\n </small>\n </span>\n </div>\n </div>\n }\n } @else {\n <div\n class=\"c8y-datapoint-pill pill--sm flex-no-shrink\"\n title=\"{{ datapoint.label }} - {{ datapoint.__target.name }}\"\n [ngClass]=\"{ active: datapoint.__active }\"\n >\n @if (!hasAtLeastOneDatapointActive && datapoint.__active) {\n <i\n class=\"text-warning m-l-4\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"'At least 1 data point must be active.' | translate\"\n container=\"body\"\n data-cy=\"datapoint-warning-icon\"\n [adaptivePosition]=\"false\"\n ></i>\n }\n <button\n class=\"c8y-datapoint-pill__btn\"\n title=\"{{\n (datapoint.__active ? hideDatapointLabel : showDatapointLabel) | translate\n }} \"\n type=\"button\"\n data-cy=\"datapoint-toggle-visibility-btn\"\n (click)=\"toggleChart(datapoint)\"\n >\n <i\n class=\"icon-14\"\n [c8yIcon]=\"datapoint.__active ? 'eye text-primary' : 'eye-slash text-muted'\"\n ></i>\n </button>\n <div class=\"c8y-datapoint-pill__label c8y-datapoint-pill__btn\">\n <i\n class=\"m-r-4 icon-14\"\n c8yIcon=\"circle\"\n [ngStyle]=\"{\n color: datapoint.color\n }\"\n ></i>\n <span\n class=\"text-truncate\"\n [ngClass]=\"{ 'text-muted': !datapoint.__active }\"\n >\n <span class=\"text-truncate text-bold\">\n {{ datapoint.label }}\n </span>\n <small class=\"text-muted text-10\">\n {{ datapoint.__target.name }}\n </small>\n </span>\n @if (datapointsOutOfSync.get(datapoint)) {\n <i\n class=\"text-warning m-l-4\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"\n 'Measurements received for this data point may be out of sync.'\n | translate\n \"\n container=\"body\"\n [adaptivePosition]=\"false\"\n ></i>\n }\n </div>\n </div>\n }\n }\n\n @for (alarm of alarms; track alarm) {\n <div\n class=\"c8y-alarm-pill pill--sm flex-no-shrink\"\n title=\"{{ alarm.filters.type }} \"\n >\n @if (displayConfig?.activeAlarmTypesOutOfRange?.includes(alarm.filters.type)) {\n <i\n class=\"text-warning m-l-4\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"\n 'Alarm of this type is currently active and outside of the selected time range'\n | translate\n \"\n container=\"body\"\n [adaptivePosition]=\"false\"\n ></i>\n }\n <button\n class=\"c8y-alarm-pill__btn\"\n title=\"{{ alarm.filters.type }} \"\n type=\"button\"\n (click)=\"toggleAlarmEventType(alarm)\"\n >\n <i\n class=\"icon-14\"\n [c8yIcon]=\"\n alarm.__hidden || !alarm.__active\n ? 'eye-slash text-muted'\n : 'eye text-primary'\n \"\n ></i>\n </button>\n <button\n class=\"c8y-alarm-pill__label c8y-alarm-pill__btn\"\n (click)=\"toggleMarkedArea(alarm)\"\n [ngClass]=\"{\n active:\n !isMarkedAreaEnabled && alarm.filters.type === enabledMarkedAreaAlarmType\n }\"\n >\n <span\n class=\"circle-icon-wrapper circle-icon-wrapper--small m-r-4\"\n [style.background-color]=\"alarm.color\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"bell\"\n ></i>\n </span>\n <span\n class=\"text-truncate\"\n [ngClass]=\"{ 'text-muted': alarm.__hidden }\"\n >\n <span class=\"text-truncate text-bold\">\n {{ alarm.label || alarm.filters.type }}\n </span>\n <small class=\"text-muted text-10\">\n {{ alarm.__target.name }}\n </small>\n </span>\n </button>\n </div>\n }\n\n @for (event of events; track event) {\n <div\n class=\"c8y-event-pill pill--sm flex-no-shrink\"\n title=\"{{ event.filters.type }}\"\n >\n <button\n class=\"c8y-event-pill__btn\"\n title=\"{{ event.filters.type }} \"\n type=\"button\"\n (click)=\"toggleAlarmEventType(event)\"\n >\n <i\n class=\"icon-14\"\n [c8yIcon]=\"\n event.__hidden || !event.__active\n ? 'eye-slash text-muted'\n : 'eye text-primary'\n \"\n ></i>\n </button>\n <div class=\"c8y-event-pill__label c8y-event-pill__btn\">\n <span\n class=\"circle-icon-wrapper circle-icon-wrapper--small m-r-4\"\n [ngStyle]=\"{ 'background-color': event.color }\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"online1\"\n ></i>\n </span>\n <span\n class=\"text-truncate text-bold\"\n [ngClass]=\"{ 'text-muted': event.__hidden }\"\n >\n <span class=\"text-truncate\">\n {{ event.label || event.filters.type }}\n </span>\n <small class=\"text-muted text-10\">\n {{ event.__target.name }}\n </small>\n </span>\n </div>\n </div>\n }\n </div>\n </div>\n <button\n class=\"btn-help btn-help--sm m-r-8\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"legendHelpTemplate\"\n placement=\"left\"\n triggers=\"focus\"\n container=\"body\"\n [adaptivePosition]=\"true\"\n ></button>\n }\n </div>\n }\n </div>\n</div>\n\n@if (displayConfig !== null) {\n <c8y-charts\n #chart\n [config]=\"displayConfig\"\n [alerts]=\"alerts\"\n [chartViewContext]=\"chartViewContext\"\n (updateAlarmsAndEvents)=\"updateAlarmsAndEvents($event)\"\n (configChangeOnZoomOut)=\"updateDashboardTimeContext($event)\"\n (datapointOutOfSync)=\"handleDatapointOutOfSync($event)\"\n (datapointBackInSync)=\"handleDatapointBackInSync($event)\"\n (finishLoading)=\"this.isLoading$.next($event)\"\n (isMarkedAreaEnabled)=\"isMarkedAreaEnabled = $event\"\n (duplicateAggregationsDetected)=\"onDuplicateAggregationsDetected($event)\"\n (selectedChange)=\"onSelectedChange($event)\"\n ></c8y-charts>\n}\n\n<ng-template #legendHelpTemplate>\n <div [innerHTML]=\"legendHelp\"></div>\n</ng-template>\n\n<c8y-widget-action>\n <c8y-datapoints-export-selector\n [displayMode]=\"'icon-only'\"\n [exportConfig]=\"exportConfig\"\n [containerClass]=\"'d-contents'\"\n ></c8y-datapoints-export-selector>\n <button\n class=\"btn btn-icon\"\n [attr.aria-label]=\"'Save as image' | translate\"\n tooltip=\"{{ 'Save as image' | translate }}\"\n container=\"body\"\n type=\"button\"\n [delay]=\"500\"\n (click)=\"chartComponent.saveAsImage()\"\n [adaptivePosition]=\"false\"\n >\n <i\n class=\"icon-14\"\n c8yIcon=\"image-file-checked\"\n ></i>\n </button>\n</c8y-widget-action>\n", dependencies: [{ kind: "ngmodule", type: A11yModule }, { kind: "ngmodule", type: CommonModule$1 }, { kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: ChartsComponent, selector: "c8y-charts", inputs: ["config", "alerts", "chartViewContext"], outputs: ["configChangeOnZoomOut", "timeRangeChangeOnRealtime", "datapointOutOfSync", "datapointBackInSync", "updateAlarmsAndEvents", "isMarkedAreaEnabled", "finishLoading", "updateActiveDatapoints", "selectedChange", "updateAggregatedSliderDatapoint", "duplicateAggregationsDetected"] }, { kind: "ngmodule", type: CoreModule }, { kind: "directive", type: i1.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "component", type: i1.SelectComponent, selector: "c8y-select", inputs: ["placeholder", "items", "selected", "container", "multi", "canSelectWithSpace", "disabled", "autoClose", "insideClick", "required", "canDeselect", "name", "icon", "filterItems"], outputs: ["onSelect", "onDeselect", "onIconClick"] }, { kind: "directive", type: i1.SelectItemDirective, selector: "[c8ySelectItem]", inputs: ["c8ySelectItem", "c8ySelectItemLabel"] }, { kind: "directive", type: i1.SelectedItemsDirective, selector: "[c8ySelectedItems]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i3.TooltipDirective, selector: "[tooltip], [tooltipHtml]", inputs: ["adaptivePosition", "tooltip", "placement", "triggers", "container", "containerClass", "boundariesElement", "isOpen", "isDisabled", "delay", "tooltipHtml", "tooltipPlacement", "tooltipIsOpen", "tooltipEnable", "tooltipAppendToBody", "tooltipAnimation", "tooltipClass", "tooltipContext", "tooltipPopupDelay", "tooltipFadeDuration", "tooltipTrigger"], outputs: ["tooltipChange", "onShown", "onHidden", "tooltipStateChanged"], exportAs: ["bs-tooltip"] }, { kind: "ngmodule", type: BsDropdownModule }, { kind: "ngmodule", type: PopoverModule }, { kind: "directive", type: i4.PopoverDirective, selector: "[popover]", inputs: ["adaptivePosition", "boundariesElement", "popover", "popoverContext", "popoverTitle", "placement", "outsideClick", "triggers", "container", "containerClass", "isOpen", "delay"], outputs: ["onShown", "onHidden"], exportAs: ["bs-popover"] }, { kind: "ngmodule", type: AlarmsModule }, { kind: "component", type: i9.AlarmsFilterComponent, selector: "c8y-alarms-filter", inputs: ["contextSourceId"], outputs: ["onFilterApplied"] }, { kind: "component", type: GlobalContextConnectorComponent, selector: "c8y-global-context-connector", inputs: ["controls", "config", "isLoading", "dashboardChild", "linked", "propagateAutoRefresh", "emitRefresh"], outputs: ["configChange", "refresh", "linkedChange"] }, { kind: "component", type: LocalControlsComponent, selector: "c8y-local-controls", inputs: ["controls", "displayMode", "config", "isLoading", "disabled", "propagateAutoRefresh", "emitRefresh", "dashboardChild"], outputs: ["configChange", "refresh"] }, { kind: "component", type: DatapointsExportSelectorComponent, selector: "c8y-datapoints-export-selector", inputs: ["displayMode", "containerClass", "exportConfig"], outputs: ["isOpen"] }, { kind: "component", type: WidgetActionWrapperComponent, selector: "c8y-widget-action" }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }, { kind: "pipe", type: i1.C8yTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
913
928
  }
914
929
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: DatapointsGraphWidgetViewComponent, decorators: [{
915
930
  type: Component,
@@ -929,7 +944,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
929
944
  SelectItemDirective,
930
945
  SelectedItemsDirective,
931
946
  WidgetActionWrapperComponent
932
- ], providers: [ChartEventsService, ChartAlarmsService, WidgetTimeContextDateRangeService], changeDetection: ChangeDetectionStrategy.Eager, template: "@if (displayMode() === GLOBAL_CONTEXT_DISPLAY_MODE.DASHBOARD) {\n <c8y-global-context-connector\n [controls]=\"widgetControls()\"\n [config]=\"contextConfig()\"\n [isLoading]=\"isLoading$ | async\"\n [dashboardChild]=\"getDashboardChild()\"\n [linked]=\"isLinkedToGlobal()\"\n [propagateAutoRefresh]=\"false\"\n (configChange)=\"onContextChange($event)\"\n ></c8y-global-context-connector>\n} @else {\n <c8y-local-controls\n [controls]=\"widgetControls()\"\n [displayMode]=\"displayMode()\"\n [config]=\"contextConfig()\"\n [isLoading]=\"isLoading$ | async\"\n [propagateAutoRefresh]=\"false\"\n (configChange)=\"onContextChange($event)\"\n ></c8y-local-controls>\n}\n\n<div\n class=\"p-l-16 p-r-16\"\n style=\"min-height: 34px\"\n>\n <div class=\"d-flex gap-16 a-i-center\">\n @if (hasAtLeastOneAlarmActive) {\n <c8y-alarms-filter\n class=\"d-contents form-group-sm min-width-0\"\n (onFilterApplied)=\"filterSeverity($event)\"\n ></c8y-alarms-filter>\n }\n @if (displayConfig?.datapoints.length > 0) {\n <div class=\"d-flex a-i-center min-width-0\">\n @if (\n displayConfig.dataPointLegendDisplay === 'dropdown' ||\n (displayConfig.dataPointLegendDisplay === 'auto' && totalLegendItems > 5)\n ) {\n <c8y-select\n class=\"min-width-0 c8y-select-v2--sm\"\n aria-label=\"{{ 'Select data points, alarms or events' | translate }}\"\n [placeholder]=\"'Select data points, alarms or events' | translate\"\n [multi]=\"true\"\n [filterItems]=\"true\"\n [(ngModel)]=\"selectedItems\"\n (onSelect)=\"onItemSelected($event)\"\n (onDeselect)=\"onItemDeselected($event)\"\n >\n @for (item of selectableItems; track item.value) {\n @let isDuplicate = isDuplicateDropdownItem(item);\n <div\n class=\"d-flex a-i-center gap-4\"\n [style.opacity]=\"isDuplicate ? '0.5' : null\"\n *c8ySelectItem=\"item.value; label: item.label\"\n >\n @if (\n !hasAtLeastOneDatapointActive &&\n item.value.type === 'DATAPOINT' &&\n (!item.value.renderTypeFn\n ? item.value.original.__active\n : isRenderTypeFunctionVisible(\n $any(item.value.original),\n item.value.renderTypeFn\n ))\n ) {\n <i\n class=\"text-warning m-r-4\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"'At least 1 data point must be active.' | translate\"\n container=\"body\"\n data-cy=\"datapoint-warning-icon\"\n [adaptivePosition]=\"false\"\n ></i>\n }\n @if (isDuplicate) {\n <i\n class=\"text-warning m-r-4\"\n c8yIcon=\"warning2\"\n [tooltip]=\"duplicateAggrWarning\"\n container=\"body\"\n [adaptivePosition]=\"false\"\n ></i>\n }\n @if (item.value.type === 'DATAPOINT') {\n @let fnColor =\n item.value.renderTypeFn\n ? $any(item.value.original).renderTypeColors?.[item.value.renderTypeFn] ||\n item.value.original.color\n : item.value.original.color;\n <span\n class=\"circle-icon-wrapper a-s-start circle-icon-wrapper--small\"\n [style.background-color]=\"fnColor\"\n ></span>\n }\n @if (item.value.type === 'ALARM') {\n <span\n class=\"circle-icon-wrapper a-s-start circle-icon-wrapper--small\"\n [style.background-color]=\"item.value.original.color\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"bell\"\n ></i>\n </span>\n }\n @if (item.value.type === 'EVENT') {\n <span\n class=\"circle-icon-wrapper a-s-start circle-icon-wrapper--small\"\n [ngStyle]=\"{ 'background-color': item.value.original.color }\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"online1\"\n ></i>\n </span>\n }\n <span class=\"text-truncate d-col\">\n <small class=\"text-truncate\">{{ item.label }}</small>\n <span class=\"text-muted text-10\">{{ item.value.original.__target?.name }}</span>\n </span>\n </div>\n }\n <span\n class=\"tag tag--info chip\"\n [style.opacity]=\"isDuplicateDropdownItem(selectedItem) ? '0.6' : null\"\n title=\"{{ selectedItem.label }}\"\n *c8ySelectedItems=\"let selectedItem\"\n >\n @let isDuplicateChip = isDuplicateDropdownItem(selectedItem);\n <button\n class=\"btn btn-xs btn-clean text-10\"\n title=\"{{ selectedItem.label }}\"\n type=\"button\"\n (click)=\"\n $event.preventDefault(); $event.stopPropagation(); onItemDeselected(selectedItem)\n \"\n >\n <i c8yIcon=\"times\"></i>\n </button>\n @if (isLastActiveDatapoint(selectedItem)) {\n <i\n class=\"text-warning a-s-start\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"'At least 1 data point must be active.' | translate\"\n container=\"body\"\n data-cy=\"datapoint-warning-icon\"\n [adaptivePosition]=\"false\"\n ></i>\n }\n @if (isDuplicateChip) {\n <i\n class=\"text-warning a-s-start\"\n c8yIcon=\"warning2\"\n [tooltip]=\"duplicateAggrWarning\"\n container=\"body\"\n [adaptivePosition]=\"false\"\n ></i>\n }\n @if (selectedItem.value.type === 'DATAPOINT') {\n @let fnColor =\n selectedItem.value.renderTypeFn\n ? $any(selectedItem.value.original).renderTypeColors?.[\n selectedItem.value.renderTypeFn\n ] || selectedItem.value.original.color\n : selectedItem.value?.original.color || '';\n <span\n class=\"circle-icon-wrapper circle-icon-wrapper--small\"\n [style.background-color]=\"fnColor\"\n ></span>\n }\n @if (selectedItem.value?.type === 'ALARM') {\n <span\n class=\"circle-icon-wrapper circle-icon-wrapper--small\"\n [style.background-color]=\"selectedItem.value?.original.color || ''\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"bell\"\n ></i>\n </span>\n }\n @if (selectedItem.value?.type === 'EVENT') {\n <span\n class=\"circle-icon-wrapper circle-icon-wrapper--small\"\n [ngStyle]=\"{\n 'background-color': selectedItem.value?.original.color || ''\n }\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"online1\"\n ></i>\n </span>\n }\n </span>\n </c8y-select>\n } @else {\n <div class=\"inner-scroll\">\n <div class=\"p-t-4 d-flex a-i-start gap-8\">\n @for (datapoint of displayConfig.datapoints; track datapoint) {\n @let rtColors = getAggregationFunctionColors(datapoint);\n @let dpId = getDpId(datapoint);\n @if (datapoint.retrievalError) {\n <i\n class=\"text-warning m-l-4\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"'Data point no longer exists.' | translate\"\n container=\"body\"\n [adaptivePosition]=\"false\"\n ></i>\n } @else if (\n rtColors.length > 0 &&\n datapointsWithDuplicateAggr.has(dpId) &&\n displayConfig?.aggregation\n ) {\n <!-- All aggregation functions return the same value \u2014 collapse to a single muted pill -->\n <div\n class=\"c8y-datapoint-pill pill--sm flex-no-shrink\"\n [class.active]=\"datapoint.__active\"\n style=\"opacity: 0.5\"\n title=\"{{ datapoint.label }} - {{ datapoint.__target.name }}\"\n >\n <button\n class=\"c8y-datapoint-pill__btn\"\n title=\"{{\n (datapoint.__active ? hideDatapointLabel : showDatapointLabel) | translate\n }}\"\n type=\"button\"\n data-cy=\"datapoint-toggle-visibility-btn\"\n (click)=\"toggleChart(datapoint)\"\n >\n <i\n class=\"icon-14\"\n [c8yIcon]=\"datapoint.__active ? 'eye text-primary' : 'eye-slash text-muted'\"\n ></i>\n </button>\n <div class=\"c8y-datapoint-pill__label c8y-datapoint-pill__btn\">\n <i\n class=\"m-r-4 icon-14\"\n c8yIcon=\"circle\"\n [style.color]=\"datapoint.color\"\n ></i>\n <span\n class=\"text-truncate\"\n [class.text-muted]=\"!datapoint.__active\"\n >\n <span class=\"text-truncate text-bold\">{{ datapoint.label }}</span>\n <small class=\"text-muted text-10\">{{ datapoint.__target.name }}</small>\n </span>\n <i\n class=\"text-warning m-l-4\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"duplicateAggrWarning\"\n container=\"body\"\n [adaptivePosition]=\"false\"\n ></i>\n </div>\n </div>\n } @else if (rtColors.length > 0) {\n @for (entry of rtColors; track entry.renderType) {\n @let isVisible = isRenderTypeFunctionVisible(datapoint, entry.renderType);\n <div\n class=\"c8y-datapoint-pill pill--sm flex-no-shrink\"\n [class.active]=\"isVisible\"\n title=\"{{ datapoint.label }} [{{ entry.renderType }}] - {{\n datapoint.__target.name\n }}\"\n >\n @if (!hasAtLeastOneDatapointActive && isVisible) {\n <i\n class=\"text-warning m-l-4\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"'At least 1 data point must be active.' | translate\"\n container=\"body\"\n data-cy=\"datapoint-warning-icon\"\n [adaptivePosition]=\"false\"\n ></i>\n }\n <button\n class=\"c8y-datapoint-pill__btn\"\n title=\"{{\n (isVisible ? hideDatapointLabel : showDatapointLabel) | translate\n }}\"\n type=\"button\"\n data-cy=\"datapoint-toggle-visibility-btn\"\n (click)=\"toggleRenderTypeFunction(datapoint, entry.renderType, !isVisible)\"\n >\n <i\n class=\"icon-14\"\n [c8yIcon]=\"isVisible ? 'eye text-primary' : 'eye-slash text-muted'\"\n ></i>\n </button>\n <div class=\"c8y-datapoint-pill__label c8y-datapoint-pill__btn\">\n <i\n class=\"m-r-4 icon-14\"\n c8yIcon=\"circle\"\n [style.color]=\"entry.color\"\n ></i>\n <span\n class=\"text-truncate\"\n [class.text-muted]=\"!isVisible\"\n >\n <span class=\"text-truncate text-bold\">\n {{ datapoint.label }} [{{ entry.renderType }}]\n </span>\n <small class=\"text-muted text-10\">\n {{ datapoint.__target.name }}\n </small>\n </span>\n </div>\n </div>\n }\n } @else {\n <div\n class=\"c8y-datapoint-pill pill--sm flex-no-shrink\"\n title=\"{{ datapoint.label }} - {{ datapoint.__target.name }}\"\n [ngClass]=\"{ active: datapoint.__active }\"\n >\n @if (!hasAtLeastOneDatapointActive && datapoint.__active) {\n <i\n class=\"text-warning m-l-4\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"'At least 1 data point must be active.' | translate\"\n container=\"body\"\n data-cy=\"datapoint-warning-icon\"\n [adaptivePosition]=\"false\"\n ></i>\n }\n <button\n class=\"c8y-datapoint-pill__btn\"\n title=\"{{\n (datapoint.__active ? hideDatapointLabel : showDatapointLabel) | translate\n }} \"\n type=\"button\"\n data-cy=\"datapoint-toggle-visibility-btn\"\n (click)=\"toggleChart(datapoint)\"\n >\n <i\n class=\"icon-14\"\n [c8yIcon]=\"datapoint.__active ? 'eye text-primary' : 'eye-slash text-muted'\"\n ></i>\n </button>\n <div class=\"c8y-datapoint-pill__label c8y-datapoint-pill__btn\">\n <i\n class=\"m-r-4 icon-14\"\n c8yIcon=\"circle\"\n [ngStyle]=\"{\n color: datapoint.color\n }\"\n ></i>\n <span\n class=\"text-truncate\"\n [ngClass]=\"{ 'text-muted': !datapoint.__active }\"\n >\n <span class=\"text-truncate text-bold\">\n {{ datapoint.label }}\n </span>\n <small class=\"text-muted text-10\">\n {{ datapoint.__target.name }}\n </small>\n </span>\n @if (datapointsOutOfSync.get(datapoint)) {\n <i\n class=\"text-warning m-l-4\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"\n 'Measurements received for this data point may be out of sync.'\n | translate\n \"\n container=\"body\"\n [adaptivePosition]=\"false\"\n ></i>\n }\n </div>\n </div>\n }\n }\n\n @for (alarm of alarms; track alarm) {\n <div\n class=\"c8y-alarm-pill pill--sm flex-no-shrink\"\n title=\"{{ alarm.filters.type }} \"\n >\n @if (displayConfig?.activeAlarmTypesOutOfRange?.includes(alarm.filters.type)) {\n <i\n class=\"text-warning m-l-4\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"\n 'Alarm of this type is currently active and outside of the selected time range'\n | translate\n \"\n container=\"body\"\n [adaptivePosition]=\"false\"\n ></i>\n }\n <button\n class=\"c8y-alarm-pill__btn\"\n title=\"{{ alarm.filters.type }} \"\n type=\"button\"\n (click)=\"toggleAlarmEventType(alarm)\"\n >\n <i\n class=\"icon-14\"\n [c8yIcon]=\"\n alarm.__hidden || !alarm.__active\n ? 'eye-slash text-muted'\n : 'eye text-primary'\n \"\n ></i>\n </button>\n <button\n class=\"c8y-alarm-pill__label c8y-alarm-pill__btn\"\n (click)=\"toggleMarkedArea(alarm)\"\n [ngClass]=\"{\n active:\n !isMarkedAreaEnabled && alarm.filters.type === enabledMarkedAreaAlarmType\n }\"\n >\n <span\n class=\"circle-icon-wrapper circle-icon-wrapper--small m-r-4\"\n [style.background-color]=\"alarm.color\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"bell\"\n ></i>\n </span>\n <span\n class=\"text-truncate\"\n [ngClass]=\"{ 'text-muted': alarm.__hidden }\"\n >\n <span class=\"text-truncate text-bold\">\n {{ alarm.label || alarm.filters.type }}\n </span>\n <small class=\"text-muted text-10\">\n {{ alarm.__target.name }}\n </small>\n </span>\n </button>\n </div>\n }\n\n @for (event of events; track event) {\n <div\n class=\"c8y-event-pill pill--sm flex-no-shrink\"\n title=\"{{ event.filters.type }}\"\n >\n <button\n class=\"c8y-event-pill__btn\"\n title=\"{{ event.filters.type }} \"\n type=\"button\"\n (click)=\"toggleAlarmEventType(event)\"\n >\n <i\n class=\"icon-14\"\n [c8yIcon]=\"\n event.__hidden || !event.__active\n ? 'eye-slash text-muted'\n : 'eye text-primary'\n \"\n ></i>\n </button>\n <div class=\"c8y-event-pill__label c8y-event-pill__btn\">\n <span\n class=\"circle-icon-wrapper circle-icon-wrapper--small m-r-4\"\n [ngStyle]=\"{ 'background-color': event.color }\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"online1\"\n ></i>\n </span>\n <span\n class=\"text-truncate text-bold\"\n [ngClass]=\"{ 'text-muted': event.__hidden }\"\n >\n <span class=\"text-truncate\">\n {{ event.label || event.filters.type }}\n </span>\n <small class=\"text-muted text-10\">\n {{ event.__target.name }}\n </small>\n </span>\n </div>\n </div>\n }\n </div>\n </div>\n <button\n class=\"btn-help btn-help--sm m-r-8\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"legendHelpTemplate\"\n placement=\"left\"\n triggers=\"focus\"\n container=\"body\"\n [adaptivePosition]=\"true\"\n ></button>\n }\n </div>\n }\n </div>\n</div>\n\n@if (displayConfig !== null) {\n <c8y-charts\n #chart\n [config]=\"displayConfig\"\n [alerts]=\"alerts\"\n [chartViewContext]=\"chartViewContext\"\n (updateAlarmsAndEvents)=\"updateAlarmsAndEvents($event)\"\n (configChangeOnZoomOut)=\"updateDashboardTimeContext($event)\"\n (datapointOutOfSync)=\"handleDatapointOutOfSync($event)\"\n (datapointBackInSync)=\"handleDatapointBackInSync($event)\"\n (finishLoading)=\"this.isLoading$.next($event)\"\n (isMarkedAreaEnabled)=\"isMarkedAreaEnabled = $event\"\n (duplicateAggregationsDetected)=\"onDuplicateAggregationsDetected($event)\"\n ></c8y-charts>\n}\n\n<ng-template #legendHelpTemplate>\n <div [innerHTML]=\"legendHelp\"></div>\n</ng-template>\n\n<c8y-widget-action>\n <c8y-datapoints-export-selector\n [displayMode]=\"'icon-only'\"\n [exportConfig]=\"exportConfig\"\n [containerClass]=\"'d-contents'\"\n ></c8y-datapoints-export-selector>\n <button\n class=\"btn btn-icon\"\n [attr.aria-label]=\"'Save as image' | translate\"\n tooltip=\"{{ 'Save as image' | translate }}\"\n container=\"body\"\n type=\"button\"\n [delay]=\"500\"\n (click)=\"chartComponent.saveAsImage()\"\n [adaptivePosition]=\"false\"\n >\n <i\n class=\"icon-14\"\n c8yIcon=\"image-file-checked\"\n ></i>\n </button>\n</c8y-widget-action>\n" }]
947
+ ], providers: [ChartEventsService, ChartAlarmsService, WidgetTimeContextDateRangeService], changeDetection: ChangeDetectionStrategy.Eager, template: "@if (displayMode() === GLOBAL_CONTEXT_DISPLAY_MODE.DASHBOARD) {\n <c8y-global-context-connector\n [controls]=\"widgetControls()\"\n [config]=\"contextConfig()\"\n [isLoading]=\"isLoading$ | async\"\n [dashboardChild]=\"getDashboardChild()\"\n [linked]=\"isLinkedToGlobal()\"\n [propagateAutoRefresh]=\"false\"\n (configChange)=\"onContextChange($event)\"\n ></c8y-global-context-connector>\n} @else {\n <c8y-local-controls\n [controls]=\"widgetControls()\"\n [displayMode]=\"displayMode()\"\n [config]=\"contextConfig()\"\n [isLoading]=\"isLoading$ | async\"\n [propagateAutoRefresh]=\"false\"\n (configChange)=\"onContextChange($event)\"\n ></c8y-local-controls>\n}\n\n<div\n class=\"p-l-16 p-r-16\"\n style=\"min-height: 34px\"\n>\n <div class=\"d-flex gap-16 a-i-center\">\n @if (hasAtLeastOneAlarmActive) {\n <c8y-alarms-filter\n class=\"d-contents form-group-sm min-width-0\"\n (onFilterApplied)=\"filterSeverity($event)\"\n ></c8y-alarms-filter>\n }\n @if (displayConfig?.datapoints.length > 0) {\n <div class=\"d-flex a-i-center min-width-0\">\n @if (\n displayConfig.dataPointLegendDisplay === 'dropdown' ||\n (displayConfig.dataPointLegendDisplay === 'auto' && totalLegendItems > 5)\n ) {\n <c8y-select\n class=\"min-width-0 c8y-select-v2--sm\"\n aria-label=\"{{ 'Select data points, alarms or events' | translate }}\"\n [placeholder]=\"'Select data points, alarms or events' | translate\"\n [multi]=\"true\"\n [filterItems]=\"true\"\n [(ngModel)]=\"selectedItems\"\n (onSelect)=\"onItemSelected($event)\"\n (onDeselect)=\"onItemDeselected($event)\"\n >\n @for (item of selectableItems; track item.value) {\n @let isDuplicate = isDuplicateDropdownItem(item);\n <div\n class=\"d-flex a-i-center gap-4\"\n [style.opacity]=\"isDuplicate ? '0.5' : null\"\n *c8ySelectItem=\"item.value; label: item.label\"\n >\n @if (\n !hasAtLeastOneDatapointActive &&\n item.value.type === 'DATAPOINT' &&\n (!item.value.renderTypeFn\n ? item.value.original.__active\n : isRenderTypeFunctionVisible(\n $any(item.value.original),\n item.value.renderTypeFn\n ))\n ) {\n <i\n class=\"text-warning m-r-4\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"'At least 1 data point must be active.' | translate\"\n container=\"body\"\n data-cy=\"datapoint-warning-icon\"\n [adaptivePosition]=\"false\"\n ></i>\n }\n @if (isDuplicate) {\n <i\n class=\"text-warning m-r-4\"\n c8yIcon=\"warning2\"\n [tooltip]=\"duplicateAggrWarning\"\n container=\"body\"\n [adaptivePosition]=\"false\"\n ></i>\n }\n @if (item.value.type === 'DATAPOINT') {\n @let fnColor =\n item.value.renderTypeFn\n ? $any(item.value.original).renderTypeColors?.[item.value.renderTypeFn] ||\n item.value.original.color\n : item.value.original.color;\n <span\n class=\"circle-icon-wrapper a-s-start circle-icon-wrapper--small\"\n [style.background-color]=\"fnColor\"\n ></span>\n }\n @if (item.value.type === 'ALARM') {\n <span\n class=\"circle-icon-wrapper a-s-start circle-icon-wrapper--small\"\n [style.background-color]=\"item.value.original.color\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"bell\"\n ></i>\n </span>\n }\n @if (item.value.type === 'EVENT') {\n <span\n class=\"circle-icon-wrapper a-s-start circle-icon-wrapper--small\"\n [ngStyle]=\"{ 'background-color': item.value.original.color }\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"online1\"\n ></i>\n </span>\n }\n <span class=\"text-truncate d-col\">\n <small class=\"text-truncate\">{{ item.label }}</small>\n <span class=\"text-muted text-10\">{{ item.value.original.__target?.name }}</span>\n </span>\n </div>\n }\n <span\n class=\"tag tag--info chip\"\n [style.opacity]=\"isDuplicateDropdownItem(selectedItem) ? '0.6' : null\"\n title=\"{{ selectedItem.label }}\"\n *c8ySelectedItems=\"let selectedItem\"\n >\n @let isDuplicateChip = isDuplicateDropdownItem(selectedItem);\n <button\n class=\"btn btn-xs btn-clean text-10\"\n title=\"{{ selectedItem.label }}\"\n type=\"button\"\n (click)=\"\n $event.preventDefault(); $event.stopPropagation(); onItemDeselected(selectedItem)\n \"\n >\n <i c8yIcon=\"times\"></i>\n </button>\n @if (isLastActiveDatapoint(selectedItem)) {\n <i\n class=\"text-warning a-s-start\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"'At least 1 data point must be active.' | translate\"\n container=\"body\"\n data-cy=\"datapoint-warning-icon\"\n [adaptivePosition]=\"false\"\n ></i>\n }\n @if (isDuplicateChip) {\n <i\n class=\"text-warning a-s-start\"\n c8yIcon=\"warning2\"\n [tooltip]=\"duplicateAggrWarning\"\n container=\"body\"\n [adaptivePosition]=\"false\"\n ></i>\n }\n @if (selectedItem.value.type === 'DATAPOINT') {\n @let fnColor =\n selectedItem.value.renderTypeFn\n ? $any(selectedItem.value.original).renderTypeColors?.[\n selectedItem.value.renderTypeFn\n ] || selectedItem.value.original.color\n : selectedItem.value?.original.color || '';\n <span\n class=\"circle-icon-wrapper circle-icon-wrapper--small\"\n [style.background-color]=\"fnColor\"\n ></span>\n }\n @if (selectedItem.value?.type === 'ALARM') {\n <span\n class=\"circle-icon-wrapper circle-icon-wrapper--small\"\n [style.background-color]=\"selectedItem.value?.original.color || ''\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"bell\"\n ></i>\n </span>\n }\n @if (selectedItem.value?.type === 'EVENT') {\n <span\n class=\"circle-icon-wrapper circle-icon-wrapper--small\"\n [ngStyle]=\"{\n 'background-color': selectedItem.value?.original.color || ''\n }\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"online1\"\n ></i>\n </span>\n }\n </span>\n </c8y-select>\n } @else {\n <div class=\"inner-scroll\">\n <div class=\"p-t-4 d-flex a-i-start gap-8\">\n @for (datapoint of displayConfig.datapoints; track datapoint) {\n @let rtColors = getAggregationFunctionColors(datapoint);\n @let dpId = getDpId(datapoint);\n @if (datapoint.retrievalError) {\n <i\n class=\"text-warning m-l-4\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"'Data point no longer exists.' | translate\"\n container=\"body\"\n [adaptivePosition]=\"false\"\n ></i>\n } @else if (\n rtColors.length > 0 &&\n datapointsWithDuplicateAggr.has(dpId) &&\n displayConfig?.aggregation\n ) {\n <!-- All aggregation functions return the same value \u2014 collapse to a single muted pill -->\n <div\n class=\"c8y-datapoint-pill pill--sm flex-no-shrink\"\n [class.active]=\"datapoint.__active\"\n style=\"opacity: 0.5\"\n title=\"{{ datapoint.label }} - {{ datapoint.__target.name }}\"\n >\n <button\n class=\"c8y-datapoint-pill__btn\"\n title=\"{{\n (datapoint.__active ? hideDatapointLabel : showDatapointLabel) | translate\n }}\"\n type=\"button\"\n data-cy=\"datapoint-toggle-visibility-btn\"\n (click)=\"toggleChart(datapoint)\"\n >\n <i\n class=\"icon-14\"\n [c8yIcon]=\"datapoint.__active ? 'eye text-primary' : 'eye-slash text-muted'\"\n ></i>\n </button>\n <div class=\"c8y-datapoint-pill__label c8y-datapoint-pill__btn\">\n <i\n class=\"m-r-4 icon-14\"\n c8yIcon=\"circle\"\n [style.color]=\"datapoint.color\"\n ></i>\n <span\n class=\"text-truncate\"\n [class.text-muted]=\"!datapoint.__active\"\n >\n <span class=\"text-truncate text-bold\">{{ datapoint.label }}</span>\n <small class=\"text-muted text-10\">{{ datapoint.__target.name }}</small>\n </span>\n <i\n class=\"text-warning m-l-4\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"duplicateAggrWarning\"\n container=\"body\"\n [adaptivePosition]=\"false\"\n ></i>\n </div>\n </div>\n } @else if (rtColors.length > 0) {\n @for (entry of rtColors; track entry.renderType) {\n @let isVisible = isRenderTypeFunctionVisible(datapoint, entry.renderType);\n <div\n class=\"c8y-datapoint-pill pill--sm flex-no-shrink\"\n [class.active]=\"isVisible\"\n title=\"{{ datapoint.label }} [{{ entry.renderType }}] - {{\n datapoint.__target.name\n }}\"\n >\n @if (!hasAtLeastOneDatapointActive && isVisible) {\n <i\n class=\"text-warning m-l-4\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"'At least 1 data point must be active.' | translate\"\n container=\"body\"\n data-cy=\"datapoint-warning-icon\"\n [adaptivePosition]=\"false\"\n ></i>\n }\n <button\n class=\"c8y-datapoint-pill__btn\"\n title=\"{{\n (isVisible ? hideDatapointLabel : showDatapointLabel) | translate\n }}\"\n type=\"button\"\n data-cy=\"datapoint-toggle-visibility-btn\"\n (click)=\"toggleRenderTypeFunction(datapoint, entry.renderType, !isVisible)\"\n >\n <i\n class=\"icon-14\"\n [c8yIcon]=\"isVisible ? 'eye text-primary' : 'eye-slash text-muted'\"\n ></i>\n </button>\n <div class=\"c8y-datapoint-pill__label c8y-datapoint-pill__btn\">\n <i\n class=\"m-r-4 icon-14\"\n c8yIcon=\"circle\"\n [style.color]=\"entry.color\"\n ></i>\n <span\n class=\"text-truncate\"\n [class.text-muted]=\"!isVisible\"\n >\n <span class=\"text-truncate text-bold\">\n {{ datapoint.label }} [{{ entry.renderType }}]\n </span>\n <small class=\"text-muted text-10\">\n {{ datapoint.__target.name }}\n </small>\n </span>\n </div>\n </div>\n }\n } @else {\n <div\n class=\"c8y-datapoint-pill pill--sm flex-no-shrink\"\n title=\"{{ datapoint.label }} - {{ datapoint.__target.name }}\"\n [ngClass]=\"{ active: datapoint.__active }\"\n >\n @if (!hasAtLeastOneDatapointActive && datapoint.__active) {\n <i\n class=\"text-warning m-l-4\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"'At least 1 data point must be active.' | translate\"\n container=\"body\"\n data-cy=\"datapoint-warning-icon\"\n [adaptivePosition]=\"false\"\n ></i>\n }\n <button\n class=\"c8y-datapoint-pill__btn\"\n title=\"{{\n (datapoint.__active ? hideDatapointLabel : showDatapointLabel) | translate\n }} \"\n type=\"button\"\n data-cy=\"datapoint-toggle-visibility-btn\"\n (click)=\"toggleChart(datapoint)\"\n >\n <i\n class=\"icon-14\"\n [c8yIcon]=\"datapoint.__active ? 'eye text-primary' : 'eye-slash text-muted'\"\n ></i>\n </button>\n <div class=\"c8y-datapoint-pill__label c8y-datapoint-pill__btn\">\n <i\n class=\"m-r-4 icon-14\"\n c8yIcon=\"circle\"\n [ngStyle]=\"{\n color: datapoint.color\n }\"\n ></i>\n <span\n class=\"text-truncate\"\n [ngClass]=\"{ 'text-muted': !datapoint.__active }\"\n >\n <span class=\"text-truncate text-bold\">\n {{ datapoint.label }}\n </span>\n <small class=\"text-muted text-10\">\n {{ datapoint.__target.name }}\n </small>\n </span>\n @if (datapointsOutOfSync.get(datapoint)) {\n <i\n class=\"text-warning m-l-4\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"\n 'Measurements received for this data point may be out of sync.'\n | translate\n \"\n container=\"body\"\n [adaptivePosition]=\"false\"\n ></i>\n }\n </div>\n </div>\n }\n }\n\n @for (alarm of alarms; track alarm) {\n <div\n class=\"c8y-alarm-pill pill--sm flex-no-shrink\"\n title=\"{{ alarm.filters.type }} \"\n >\n @if (displayConfig?.activeAlarmTypesOutOfRange?.includes(alarm.filters.type)) {\n <i\n class=\"text-warning m-l-4\"\n c8yIcon=\"exclamation-triangle\"\n [tooltip]=\"\n 'Alarm of this type is currently active and outside of the selected time range'\n | translate\n \"\n container=\"body\"\n [adaptivePosition]=\"false\"\n ></i>\n }\n <button\n class=\"c8y-alarm-pill__btn\"\n title=\"{{ alarm.filters.type }} \"\n type=\"button\"\n (click)=\"toggleAlarmEventType(alarm)\"\n >\n <i\n class=\"icon-14\"\n [c8yIcon]=\"\n alarm.__hidden || !alarm.__active\n ? 'eye-slash text-muted'\n : 'eye text-primary'\n \"\n ></i>\n </button>\n <button\n class=\"c8y-alarm-pill__label c8y-alarm-pill__btn\"\n (click)=\"toggleMarkedArea(alarm)\"\n [ngClass]=\"{\n active:\n !isMarkedAreaEnabled && alarm.filters.type === enabledMarkedAreaAlarmType\n }\"\n >\n <span\n class=\"circle-icon-wrapper circle-icon-wrapper--small m-r-4\"\n [style.background-color]=\"alarm.color\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"bell\"\n ></i>\n </span>\n <span\n class=\"text-truncate\"\n [ngClass]=\"{ 'text-muted': alarm.__hidden }\"\n >\n <span class=\"text-truncate text-bold\">\n {{ alarm.label || alarm.filters.type }}\n </span>\n <small class=\"text-muted text-10\">\n {{ alarm.__target.name }}\n </small>\n </span>\n </button>\n </div>\n }\n\n @for (event of events; track event) {\n <div\n class=\"c8y-event-pill pill--sm flex-no-shrink\"\n title=\"{{ event.filters.type }}\"\n >\n <button\n class=\"c8y-event-pill__btn\"\n title=\"{{ event.filters.type }} \"\n type=\"button\"\n (click)=\"toggleAlarmEventType(event)\"\n >\n <i\n class=\"icon-14\"\n [c8yIcon]=\"\n event.__hidden || !event.__active\n ? 'eye-slash text-muted'\n : 'eye text-primary'\n \"\n ></i>\n </button>\n <div class=\"c8y-event-pill__label c8y-event-pill__btn\">\n <span\n class=\"circle-icon-wrapper circle-icon-wrapper--small m-r-4\"\n [ngStyle]=\"{ 'background-color': event.color }\"\n >\n <i\n class=\"stroked-icon\"\n c8yIcon=\"online1\"\n ></i>\n </span>\n <span\n class=\"text-truncate text-bold\"\n [ngClass]=\"{ 'text-muted': event.__hidden }\"\n >\n <span class=\"text-truncate\">\n {{ event.label || event.filters.type }}\n </span>\n <small class=\"text-muted text-10\">\n {{ event.__target.name }}\n </small>\n </span>\n </div>\n </div>\n }\n </div>\n </div>\n <button\n class=\"btn-help btn-help--sm m-r-8\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"legendHelpTemplate\"\n placement=\"left\"\n triggers=\"focus\"\n container=\"body\"\n [adaptivePosition]=\"true\"\n ></button>\n }\n </div>\n }\n </div>\n</div>\n\n@if (displayConfig !== null) {\n <c8y-charts\n #chart\n [config]=\"displayConfig\"\n [alerts]=\"alerts\"\n [chartViewContext]=\"chartViewContext\"\n (updateAlarmsAndEvents)=\"updateAlarmsAndEvents($event)\"\n (configChangeOnZoomOut)=\"updateDashboardTimeContext($event)\"\n (datapointOutOfSync)=\"handleDatapointOutOfSync($event)\"\n (datapointBackInSync)=\"handleDatapointBackInSync($event)\"\n (finishLoading)=\"this.isLoading$.next($event)\"\n (isMarkedAreaEnabled)=\"isMarkedAreaEnabled = $event\"\n (duplicateAggregationsDetected)=\"onDuplicateAggregationsDetected($event)\"\n (selectedChange)=\"onSelectedChange($event)\"\n ></c8y-charts>\n}\n\n<ng-template #legendHelpTemplate>\n <div [innerHTML]=\"legendHelp\"></div>\n</ng-template>\n\n<c8y-widget-action>\n <c8y-datapoints-export-selector\n [displayMode]=\"'icon-only'\"\n [exportConfig]=\"exportConfig\"\n [containerClass]=\"'d-contents'\"\n ></c8y-datapoints-export-selector>\n <button\n class=\"btn btn-icon\"\n [attr.aria-label]=\"'Save as image' | translate\"\n tooltip=\"{{ 'Save as image' | translate }}\"\n container=\"body\"\n type=\"button\"\n [delay]=\"500\"\n (click)=\"chartComponent.saveAsImage()\"\n [adaptivePosition]=\"false\"\n >\n <i\n class=\"icon-14\"\n c8yIcon=\"image-file-checked\"\n ></i>\n </button>\n</c8y-widget-action>\n" }]
933
948
  }], ctorParameters: () => [{ type: i1$1.TranslateService }, { type: i2$1.ContextDashboardComponent, decorators: [{
934
949
  type: Optional
935
950
  }] }, { type: i3$1.WidgetConfigMigrationService }, { type: i1.WidgetTimeContextDateRangeService }, { type: i0.ChangeDetectorRef }], propDecorators: { config: [{