@ruc-lib/metered-progress-bar 3.1.0 → 3.2.0

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.
@@ -0,0 +1,58 @@
1
+ import { CategoryConfig, MeteredBarConfig } from '../model/metered-bar.config';
2
+ import { LablePositionEnums } from '../enums/lable-position.enum';
3
+ import * as i0 from "@angular/core";
4
+ export declare class RucMeteredProgressBarComponent {
5
+ rucInputData: MeteredBarConfig;
6
+ customTheme: string;
7
+ hoveredCategoryDetail: {
8
+ category: CategoryConfig;
9
+ percentageText: string;
10
+ } | null;
11
+ hoverLabelStyle: {
12
+ left: string;
13
+ top: string;
14
+ display: string;
15
+ transform: string;
16
+ };
17
+ progressPercentage: number;
18
+ /**
19
+ * Calculates the total value of all categories.
20
+ * @returns The sum of all category values.
21
+ */
22
+ get totalValue(): number;
23
+ /**
24
+ * Calculates the overall progress percentage of the bar based on total value, min, and max.
25
+ * @returns The progress as a percentage (0-100).
26
+ */
27
+ get progress(): number;
28
+ /**
29
+ * Determines if the progress bar is oriented vertically.
30
+ * @returns True if the orientation is 'vertical', false otherwise.
31
+ */
32
+ get isVertical(): boolean;
33
+ /**
34
+ * Generates the CSS linear-gradient string for the progress bar.
35
+ * The gradient is composed of segments based on category values and colors.
36
+ * If no categories or total value is zero, it returns a transparent gradient.
37
+ * @returns A CSS linear-gradient string.
38
+ */
39
+ get progressStyles(): {
40
+ [key: string]: string;
41
+ };
42
+ /**
43
+ * Handles mouse movement over the progress bar to display category-specific hover details.
44
+ * It calculates the hovered segment based on mouse position and updates the hover label.
45
+ * @param event The MouseEvent object.
46
+ */
47
+ onProgressMouseMove(event: MouseEvent): void;
48
+ /**
49
+ * Hides the hover label when the mouse leaves the progress bar.
50
+ */
51
+ onProgressMouseLeave(): void;
52
+ /**
53
+ * get the label position string value
54
+ */
55
+ get LablePositionEnums(): typeof LablePositionEnums;
56
+ static ɵfac: i0.ɵɵFactoryDeclaration<RucMeteredProgressBarComponent, never>;
57
+ static ɵcmp: i0.ɵɵComponentDeclaration<RucMeteredProgressBarComponent, "uxp-ruclib-metered-progress-bar", never, { "rucInputData": "rucInputData"; "customTheme": "customTheme"; }, {}, never, never, false, never>;
58
+ }
@@ -0,0 +1,10 @@
1
+ import * as i0 from "@angular/core";
2
+ import * as i1 from "./ruc-metered-progress-bar/ruc-metered-progress-bar.component";
3
+ import * as i2 from "@angular/common";
4
+ import * as i3 from "@angular/material/icon";
5
+ import * as i4 from "@angular/material/card";
6
+ export declare class RuclibMeteredProgressBarModule {
7
+ static ɵfac: i0.ɵɵFactoryDeclaration<RuclibMeteredProgressBarModule, never>;
8
+ static ɵmod: i0.ɵɵNgModuleDeclaration<RuclibMeteredProgressBarModule, [typeof i1.RucMeteredProgressBarComponent], [typeof i2.CommonModule, typeof i3.MatIconModule, typeof i4.MatCardModule], [typeof i1.RucMeteredProgressBarComponent]>;
9
+ static ɵinj: i0.ɵɵInjectorDeclaration<RuclibMeteredProgressBarModule>;
10
+ }
package/package.json CHANGED
@@ -1,16 +1,24 @@
1
1
  {
2
2
  "name": "@ruc-lib/metered-progress-bar",
3
- "version": "3.1.0",
3
+ "version": "3.2.0",
4
+ "license": "MIT",
4
5
  "peerDependencies": {
5
- "@angular/common": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0",
6
- "@angular/core": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0",
7
- "@angular/material": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0"
6
+ "@angular/common": "^17.0.0 || ^16.0.0 || ^15.0.0",
7
+ "@angular/core": "^17.0.0 || ^16.0.0 || ^15.0.0",
8
+ "@angular/material": "^15.2.9 || ^14.0.0 || ^13.0.0"
8
9
  },
9
10
  "dependencies": {
10
11
  "tslib": "^2.3.0"
11
12
  },
13
+ "publishConfig": {
14
+ "access": "public"
15
+ },
12
16
  "sideEffects": false,
13
- "module": "fesm2022/ruc-lib-metered-progress-bar.mjs",
17
+ "module": "fesm2015/ruc-lib-metered-progress-bar.mjs",
18
+ "es2020": "fesm2020/ruc-lib-metered-progress-bar.mjs",
19
+ "esm2020": "esm2020/ruc-lib-metered-progress-bar.mjs",
20
+ "fesm2020": "fesm2020/ruc-lib-metered-progress-bar.mjs",
21
+ "fesm2015": "fesm2015/ruc-lib-metered-progress-bar.mjs",
14
22
  "typings": "index.d.ts",
15
23
  "exports": {
16
24
  "./package.json": {
@@ -18,7 +26,11 @@
18
26
  },
19
27
  ".": {
20
28
  "types": "./index.d.ts",
21
- "default": "./fesm2022/ruc-lib-metered-progress-bar.mjs"
29
+ "esm2020": "./esm2020/ruc-lib-metered-progress-bar.mjs",
30
+ "es2020": "./fesm2020/ruc-lib-metered-progress-bar.mjs",
31
+ "es2015": "./fesm2015/ruc-lib-metered-progress-bar.mjs",
32
+ "node": "./fesm2015/ruc-lib-metered-progress-bar.mjs",
33
+ "default": "./fesm2020/ruc-lib-metered-progress-bar.mjs"
22
34
  }
23
35
  }
24
36
  }
@@ -1,233 +0,0 @@
1
- import * as i0 from '@angular/core';
2
- import { Input, Component } from '@angular/core';
3
- import * as i1 from '@angular/common';
4
- import { CommonModule } from '@angular/common';
5
- import { MatIconModule } from '@angular/material/icon';
6
- import * as i2 from '@angular/material/card';
7
- import { MatCardModule } from '@angular/material/card';
8
-
9
- class MeteredBarConfig {
10
- }
11
- class CategoryConfig {
12
- }
13
-
14
- var LablePositionEnums;
15
- (function (LablePositionEnums) {
16
- LablePositionEnums["left"] = "left";
17
- LablePositionEnums["right"] = "right";
18
- LablePositionEnums["same"] = "same";
19
- LablePositionEnums["top"] = "top";
20
- LablePositionEnums["bottom"] = "bottom";
21
- })(LablePositionEnums || (LablePositionEnums = {}));
22
-
23
- class RuclibMeteredProgressBarComponent {
24
- constructor() {
25
- this.hoveredCategoryDetail = null;
26
- this.hoverLabelStyle = {
27
- left: '0px',
28
- top: '-28px',
29
- display: 'none',
30
- transform: 'translateX(-50%)',
31
- };
32
- this.progressPercentage = 0;
33
- }
34
- /**
35
- * Calculates the total value of all categories.
36
- * @returns The sum of all category values.
37
- */
38
- get totalValue() {
39
- return this.rucInputData.categories.reduce((sum, category) => sum + category.value, 0);
40
- }
41
- /**
42
- * Calculates the overall progress percentage of the bar based on total value, min, and max.
43
- * @returns The progress as a percentage (0-100).
44
- */
45
- get progress() {
46
- return (((this.totalValue - this.rucInputData.min) /
47
- (this.rucInputData.max - this.rucInputData.min)) *
48
- 100);
49
- }
50
- /**
51
- * Determines if the progress bar is oriented vertically.
52
- * @returns True if the orientation is 'vertical', false otherwise.
53
- */
54
- get isVertical() {
55
- return this.rucInputData.orientation === 'vertical';
56
- }
57
- /**
58
- * Generates the CSS linear-gradient string for the progress bar.
59
- * The gradient is composed of segments based on category values and colors.
60
- * If no categories or total value is zero, it returns a transparent gradient.
61
- * @returns A CSS linear-gradient string.
62
- */
63
- get progressStyles() {
64
- const direction = this.isVertical ? 'to bottom' : 'to right';
65
- if (!this.rucInputData || !this.rucInputData.categories) {
66
- return { background: 'transparent' };
67
- }
68
- const total = this.totalValue;
69
- const colorStops = [];
70
- let cumulativePercentage = 0;
71
- if (total > 0) {
72
- this.rucInputData.categories.forEach((category) => {
73
- if (category.value <= 0)
74
- return; // Skip categories with zero or negative contribution
75
- const segmentPercentage = (category.value / total) * 100;
76
- const color = category.color;
77
- // Add start of the segment using the previous cumulative percentage
78
- colorStops.push(`${color} ${cumulativePercentage}%`);
79
- // Update cumulative percentage for the end of this segment
80
- cumulativePercentage += segmentPercentage;
81
- // Add end of the segment
82
- // Use Math.min to cap at 100% in case of floating point overshoot on the last segment
83
- colorStops.push(`${color} ${Math.min(cumulativePercentage, 100)}%`);
84
- });
85
- }
86
- if (colorStops.length === 0) {
87
- return { background: 'transparent' };
88
- }
89
- const baseGradient = `linear-gradient(${direction}, ${colorStops.join(', ')})`;
90
- const styles = {};
91
- const barStyle = this.rucInputData?.barStyle;
92
- switch (barStyle) {
93
- case 'stripe':
94
- // This uses multiple backgrounds for an overlay effect, as requested.
95
- styles['background'] = `repeating-linear-gradient(-45deg, transparent, transparent 5px, rgba(0, 0, 0, 0.1) 5px, rgba(0, 0, 0, 0.1) 10px), ${baseGradient}`;
96
- break;
97
- case 'circle': {
98
- // This uses a mask. The background is the color, the mask cuts out the shape.
99
- styles['background'] = baseGradient;
100
- // A repeating pattern of circles. Each circle has a diameter of 8px, with a 4px gap.
101
- const circleMask = 'radial-gradient(circle, black 4px, transparent 4px) 0 0 / 12px 12px';
102
- styles['-webkit-mask'] = circleMask;
103
- styles['mask'] = circleMask;
104
- break;
105
- }
106
- case 'rectangle': {
107
- styles['background'] = baseGradient;
108
- // For vertical bar, create horizontal rectangles (0deg). For horizontal bar, create vertical rectangles (90deg).
109
- const rectDirection = this.isVertical ? '0deg' : '90deg';
110
- // A repeating pattern of bars. Each bar is 6px wide with a 6px gap.
111
- const rectangleMask = `repeating-linear-gradient(${rectDirection}, black, black 6px, transparent 6px, transparent 12px)`;
112
- styles['-webkit-mask'] = rectangleMask;
113
- styles['mask'] = rectangleMask;
114
- break;
115
- }
116
- default: // 'solid' or undefined
117
- styles['background'] = baseGradient;
118
- break;
119
- }
120
- return styles;
121
- }
122
- /**
123
- * Handles mouse movement over the progress bar to display category-specific hover details.
124
- * It calculates the hovered segment based on mouse position and updates the hover label.
125
- * @param event The MouseEvent object.
126
- */
127
- onProgressMouseMove(event) {
128
- const progressBarElement = event.target;
129
- let currentCumulativeGradientPct = 0;
130
- let foundCategoryForHover = null;
131
- let hoverPercentage_onFilledBar = 0;
132
- let mousePositionWithinProgressDiv = 0;
133
- if (this.isVertical) {
134
- mousePositionWithinProgressDiv = event.offsetY; // Y position within the .progress div
135
- const filledHeightPx = progressBarElement.offsetHeight;
136
- if (filledHeightPx <= 0) {
137
- // Avoid division by zero if element has no height
138
- this.onProgressMouseLeave();
139
- return;
140
- }
141
- hoverPercentage_onFilledBar =
142
- (mousePositionWithinProgressDiv / filledHeightPx) * 100;
143
- }
144
- else {
145
- // Horizontal
146
- mousePositionWithinProgressDiv = event.offsetX; // X position within the .progress div
147
- const filledWidthPx = progressBarElement.offsetWidth;
148
- if (filledWidthPx <= 0) {
149
- // Avoid division by zero if element has no width
150
- this.onProgressMouseLeave();
151
- return;
152
- }
153
- hoverPercentage_onFilledBar =
154
- (mousePositionWithinProgressDiv / filledWidthPx) * 100;
155
- }
156
- if (this.totalValue > 0) {
157
- for (const category of this.rucInputData.categories) {
158
- if (category.value <= 0)
159
- continue; // Skip categories with zero or negative contribution
160
- const segmentGradientPct = (category.value / this.totalValue) * 100;
161
- const segmentStartGradientPct = currentCumulativeGradientPct;
162
- const segmentEndGradientPct = currentCumulativeGradientPct + segmentGradientPct;
163
- // Ensure hoverPercentage is within the segment, handling potential floating point inaccuracies for the last segment
164
- if (hoverPercentage_onFilledBar >= segmentStartGradientPct && // Check if mouse is within or at the start of the segment
165
- (hoverPercentage_onFilledBar < segmentEndGradientPct ||
166
- (segmentEndGradientPct >= 99.99 &&
167
- hoverPercentage_onFilledBar <= 100.01))) {
168
- // Tolerate slight overshoot for last segment
169
- foundCategoryForHover = category;
170
- break;
171
- }
172
- currentCumulativeGradientPct = segmentEndGradientPct;
173
- }
174
- }
175
- if (foundCategoryForHover) {
176
- const percentageOfMax = (foundCategoryForHover.value / this.rucInputData.max) * 100; // Calculate percentage relative to max value
177
- this.hoveredCategoryDetail = {
178
- category: foundCategoryForHover,
179
- percentageText: percentageOfMax.toFixed(0) + '%',
180
- };
181
- if (this.isVertical) {
182
- this.hoverLabelStyle = {
183
- left: 'calc(100% + 5px)', // Position to the right of the vertical bar
184
- top: mousePositionWithinProgressDiv + 'px',
185
- display: 'block',
186
- transform: 'translateY(-50%)', // Vertically center label on mouse Y
187
- };
188
- }
189
- else {
190
- this.hoverLabelStyle = {
191
- left: mousePositionWithinProgressDiv + 'px',
192
- top: '-28px', // Position above horizontal bar
193
- display: 'block',
194
- transform: 'translateX(-50%)', // Horizontally center label on mouse X
195
- };
196
- }
197
- }
198
- else {
199
- this.hoveredCategoryDetail = null;
200
- this.hoverLabelStyle = { ...this.hoverLabelStyle, display: 'none' };
201
- }
202
- }
203
- /**
204
- * Hides the hover label when the mouse leaves the progress bar.
205
- */
206
- onProgressMouseLeave() {
207
- this.hoveredCategoryDetail = null;
208
- this.hoverLabelStyle = { ...this.hoverLabelStyle, display: 'none' };
209
- }
210
- /**
211
- * get the label position string value
212
- */
213
- get LablePositionEnums() {
214
- return LablePositionEnums;
215
- }
216
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: RuclibMeteredProgressBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
217
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: RuclibMeteredProgressBarComponent, isStandalone: true, selector: "uxp-metered-progress-bar", inputs: { rucInputData: "rucInputData", customTheme: "customTheme" }, ngImport: i0, template: "<div class=\"progress-container\" class={{customTheme}} [class.vertical]=\"isVertical\" [class.horizontal]=\"!isVertical\">\r\n <div class=\"progress-bar\">\r\n <!-- Removed (mouseenter) and (mouseleave) from progress-bar if only category hover is needed -->\r\n @if (rucInputData.barLabels) {\r\n <div class=\"progress-label-container {{rucInputData.orientation}}\">\r\n <p class=\"progress-label\">{{progress | number:'1.0-0'}}% of {{rucInputData.max}} {{rucInputData.unitType}}\r\n Used</p>\r\n </div>\r\n }\r\n <!-- <mat-progress-bar> -->\r\n <div class=\"progress\" [style.width]=\"isVertical ? '100%' : progress + '%'\"\r\n [style.height]=\"isVertical ? progress + '%' : '100%'\"\r\n [style.transition]=\"rucInputData.orientation === 'vertical' ? 'height 0.3s ease' : 'width 0.3s ease'\"\r\n [ngStyle]=\"progressStyles\">\r\n <!-- This div is now only for displaying the colored bar -->\r\n </div>\r\n <!-- </mat-progress-bar> -->\r\n <!-- The hover label is now a sibling to .progress, positioned absolutely within .progress-bar -->\r\n @if (hoveredCategoryDetail) {\r\n <div class=\"hover-label\" [ngStyle]=\"hoverLabelStyle\">\r\n {{hoveredCategoryDetail.category.label}}: {{hoveredCategoryDetail.percentageText}}\r\n </div>\r\n }\r\n <!-- This overlay is now a sibling to .progress, sized to match it, to reliably capture mouse events -->\r\n <div class=\"progress-event-overlay\" [style.width]=\"isVertical ? '100%' : progress + '%'\"\r\n [style.height]=\"isVertical ? progress + '%' : '100%'\" (mousemove)=\"onProgressMouseMove($event)\"\r\n (mouseleave)=\"onProgressMouseLeave()\"></div>\r\n</div>\r\n@if (rucInputData.categories.length > 0) {\r\n <div class=\"categories-container\">\r\n @if (rucInputData.showCategoryLabels && rucInputData.categoryLabelStyle === 'basic') {\r\n<div [ngClass]=\"{\r\n 'categories-block-top': !isVertical && (rucInputData.categoryLabelsOrientation === 'top' || rucInputData.categoryLabelsOrientation === 'same'),\r\n 'categories-block-left': isVertical && (rucInputData.categoryLabelsOrientation === 'left' || rucInputData.categoryLabelsOrientation === 'same'),\r\n 'categories-block-right': isVertical && !(rucInputData.categoryLabelsOrientation === 'left' || rucInputData.categoryLabelsOrientation === 'same')\r\n }\" class=\"categories\">\r\n @for (category of rucInputData.categories; track category) {\r\n <div class=\"category\" [style.color]=\"category.color\">\r\n @if (category.icon !== undefined) {\r\n @if (category.icon) {\r\n <div class=\"category-icon-wrapper\">\r\n <i class=\"material-icons\" [style.color]=\"category.color\">{{ category.icon }}</i>\r\n </div>\r\n } @else {\r\n <div class=\"category-color\">\r\n <div class=\"color-gradient\"\r\n [style.background]=\"category.color ? 'linear-gradient(to right, ' + category.color + ', ' + category.color + ')' : ''\">\r\n </div>\r\n </div>\r\n }\r\n }\r\n <span class=\"category-label\">{{category.label}}</span>\r\n <p class=\"category-value\">({{(category.value / rucInputData.max * 100) | number:'1.0-0' }}%)</p>\r\n </div>\r\n }\r\n </div>\r\n }\r\n @if (rucInputData.showCategoryLabels && rucInputData.categoryLabelStyle === 'widget') {\r\n <div\r\n class=\"categories widget-style\" [ngClass]=\"{\r\n 'categories-block-top': !isVertical && (rucInputData.categoryLabelsOrientation === LablePositionEnums.top || rucInputData.categoryLabelsOrientation === LablePositionEnums.same),\r\n 'categories-block-left': isVertical && (rucInputData.categoryLabelsOrientation === LablePositionEnums.left || rucInputData.categoryLabelsOrientation === LablePositionEnums.same),\r\n 'categories-block-right': isVertical && !(rucInputData.categoryLabelsOrientation === LablePositionEnums.left || rucInputData.categoryLabelsOrientation === LablePositionEnums.same)\r\n }\">\r\n @for (category of rucInputData.categories; track category) {\r\n <mat-card>\r\n <div class=\"widget-category\">\r\n <div class=\"widget-content\">\r\n <div class=\"widget-icon-box\">\r\n @if (category.icon !== undefined) {\r\n @if (category.icon) {\r\n <div class=\"widget-icon\">\r\n <i class=\"material-icons\" [style.color]=\"category.color\">{{ category.icon }}</i>\r\n </div>\r\n } @else {\r\n <div class=\"category-color\">\r\n <div class=\"color-gradient\"\r\n [style.background]=\"category.color ? 'linear-gradient(to right, ' + category.color + ', ' + category.color + ')' : ''\">\r\n </div>\r\n </div>\r\n }\r\n }\r\n <div class=\"widget-label\">{{category.label}}</div>\r\n </div>\r\n </div>\r\n <div class=\"widget-value\">\r\n <div>{{category.value}}</div>\r\n </div>\r\n </div>\r\n </mat-card>\r\n }\r\n </div>\r\n }\r\n </div>\r\n}\r\n</div>", styles: [".progress-container{position:relative;margin:20px 0}.progress-container.horizontal{width:100%;height:35px}.progress-container.horizontal .progress-bar{width:100%;height:42%}.progress-container.vertical{width:60px;height:320px;margin:0 auto}.progress-container.vertical .progress-bar{width:24%;height:100%}.progress-label-container{position:absolute;z-index:2;width:100%;height:100%;pointer-events:none;display:flex}.progress-label-container.horizontal{justify-content:right;align-items:flex-end;bottom:15px}.progress-label-container.vertical{justify-content:flex-start;align-items:flex-end;left:35px}.progress-label{padding:2px 5px;font-size:12px;white-space:nowrap}.progress-label-container.horizontal .progress-label{margin-top:5px;margin-right:5px}.progress-label-container.vertical .progress-label{transform:rotate(-90deg);transform-origin:bottom left;margin-right:5px}.progress-bar{position:relative;border:1px solid #e0e0e0;border-radius:4px}.progress-bar .hover-label{position:absolute;top:-28px;left:50%;transform:translate(-50%);background-color:#000c;color:#fff;padding:4px 8px;border-radius:4px;font-size:.8em;z-index:5;white-space:nowrap;pointer-events:none}.progress-event-overlay{position:absolute;top:0;left:0;z-index:4}.progress{position:relative;background:#2196f3;transition:width .3s ease,height .3s ease}.progress-bar.horizontal .progress{width:100%;height:100%}.progress-bar.vertical .progress{width:100%;height:0}.icons-container{position:absolute;display:flex;justify-content:space-between;width:100%;height:100%;align-items:center}.icons-container i{position:absolute;font-size:1.2em;color:#fff}.start-icon{left:0}.end-icon{right:0}.above-threshold{color:gold}.categories-container{width:100%;box-sizing:border-box}.categories{display:flex;flex-direction:row;flex-wrap:wrap;gap:1px}.categories-block-top,.categories-block-bottom,.categories-block-left,.categories-block-right{position:absolute;z-index:1}.categories-block-top{bottom:100%;left:0;padding-bottom:8px}.categories-block-bottom{top:100%;left:0;padding-top:10px}.categories-block-left{right:100%;top:0;padding-right:8px;width:200px}.categories-block-left .categories{flex-direction:inherit;align-items:flex-start;gap:0px}.categories-block-right{left:100%;top:0;padding-left:8px;width:200px}.categories-block-right .categories{flex-direction:inherit;align-items:flex-start;gap:0px}.category{display:flex;align-items:center;gap:6px;padding:8px;border-radius:4px}.category-label{font-weight:500}.category-value{font-size:.9em}.category-color{width:10px;height:10px;border-radius:50%;overflow:hidden;flex-shrink:0}.category-icon-wrapper{display:flex;align-items:center;justify-content:center;width:100%;height:100%}.color-gradient{width:100%;height:100%}.categories.widget-style{display:flex;flex-wrap:wrap;gap:10px;justify-content:flex-start;align-items:flex-start;margin:10px 0}.categories.widget-style .widget-category{width:calc(25% - 7.5px);min-width:159px;box-sizing:border-box;flex-shrink:0;flex-grow:0}@media (max-width: 1200px){.categories.widget-style .widget-category{width:calc(33.33% - 6.66px)}}@media (max-width: 768px){.categories.widget-style .widget-category{width:calc(50% - 5px)}}@media (max-width: 480px){.categories.widget-style .widget-category{width:100%}}.categories-block-left,.categories-block-right{flex-direction:inherit;align-items:flex-start;gap:10px}.categories-block-left .widget-category,.categories-block-right .widget-category{width:100%;max-width:none}.widget-category{padding:10px 15px}.widget-content{display:flex;width:100%;align-items:center;margin:0}.widget-icon{border:1px solid #ddd;border-radius:10px;width:35px;height:35px;line-height:45px;text-align:center;background-color:#fdfdfd}.widget-content .category-color{margin-right:35px}.widget-icon,.widget-color{margin-right:8px;flex-shrink:0}.widget-color{width:24px;height:24px;border-radius:50%}.widget-label{flex-grow:1;text-align:left;display:block}.widget-value{font-weight:700;flex-shrink:0;margin-left:45px;text-align:left;margin-top:5px}.widget-icon-box{display:flex;align-items:center}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i2.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "pipe", type: i1.DecimalPipe, name: "number" }] }); }
218
- }
219
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: RuclibMeteredProgressBarComponent, decorators: [{
220
- type: Component,
221
- args: [{ selector: 'uxp-metered-progress-bar', imports: [CommonModule, MatIconModule, MatCardModule], template: "<div class=\"progress-container\" class={{customTheme}} [class.vertical]=\"isVertical\" [class.horizontal]=\"!isVertical\">\r\n <div class=\"progress-bar\">\r\n <!-- Removed (mouseenter) and (mouseleave) from progress-bar if only category hover is needed -->\r\n @if (rucInputData.barLabels) {\r\n <div class=\"progress-label-container {{rucInputData.orientation}}\">\r\n <p class=\"progress-label\">{{progress | number:'1.0-0'}}% of {{rucInputData.max}} {{rucInputData.unitType}}\r\n Used</p>\r\n </div>\r\n }\r\n <!-- <mat-progress-bar> -->\r\n <div class=\"progress\" [style.width]=\"isVertical ? '100%' : progress + '%'\"\r\n [style.height]=\"isVertical ? progress + '%' : '100%'\"\r\n [style.transition]=\"rucInputData.orientation === 'vertical' ? 'height 0.3s ease' : 'width 0.3s ease'\"\r\n [ngStyle]=\"progressStyles\">\r\n <!-- This div is now only for displaying the colored bar -->\r\n </div>\r\n <!-- </mat-progress-bar> -->\r\n <!-- The hover label is now a sibling to .progress, positioned absolutely within .progress-bar -->\r\n @if (hoveredCategoryDetail) {\r\n <div class=\"hover-label\" [ngStyle]=\"hoverLabelStyle\">\r\n {{hoveredCategoryDetail.category.label}}: {{hoveredCategoryDetail.percentageText}}\r\n </div>\r\n }\r\n <!-- This overlay is now a sibling to .progress, sized to match it, to reliably capture mouse events -->\r\n <div class=\"progress-event-overlay\" [style.width]=\"isVertical ? '100%' : progress + '%'\"\r\n [style.height]=\"isVertical ? progress + '%' : '100%'\" (mousemove)=\"onProgressMouseMove($event)\"\r\n (mouseleave)=\"onProgressMouseLeave()\"></div>\r\n</div>\r\n@if (rucInputData.categories.length > 0) {\r\n <div class=\"categories-container\">\r\n @if (rucInputData.showCategoryLabels && rucInputData.categoryLabelStyle === 'basic') {\r\n<div [ngClass]=\"{\r\n 'categories-block-top': !isVertical && (rucInputData.categoryLabelsOrientation === 'top' || rucInputData.categoryLabelsOrientation === 'same'),\r\n 'categories-block-left': isVertical && (rucInputData.categoryLabelsOrientation === 'left' || rucInputData.categoryLabelsOrientation === 'same'),\r\n 'categories-block-right': isVertical && !(rucInputData.categoryLabelsOrientation === 'left' || rucInputData.categoryLabelsOrientation === 'same')\r\n }\" class=\"categories\">\r\n @for (category of rucInputData.categories; track category) {\r\n <div class=\"category\" [style.color]=\"category.color\">\r\n @if (category.icon !== undefined) {\r\n @if (category.icon) {\r\n <div class=\"category-icon-wrapper\">\r\n <i class=\"material-icons\" [style.color]=\"category.color\">{{ category.icon }}</i>\r\n </div>\r\n } @else {\r\n <div class=\"category-color\">\r\n <div class=\"color-gradient\"\r\n [style.background]=\"category.color ? 'linear-gradient(to right, ' + category.color + ', ' + category.color + ')' : ''\">\r\n </div>\r\n </div>\r\n }\r\n }\r\n <span class=\"category-label\">{{category.label}}</span>\r\n <p class=\"category-value\">({{(category.value / rucInputData.max * 100) | number:'1.0-0' }}%)</p>\r\n </div>\r\n }\r\n </div>\r\n }\r\n @if (rucInputData.showCategoryLabels && rucInputData.categoryLabelStyle === 'widget') {\r\n <div\r\n class=\"categories widget-style\" [ngClass]=\"{\r\n 'categories-block-top': !isVertical && (rucInputData.categoryLabelsOrientation === LablePositionEnums.top || rucInputData.categoryLabelsOrientation === LablePositionEnums.same),\r\n 'categories-block-left': isVertical && (rucInputData.categoryLabelsOrientation === LablePositionEnums.left || rucInputData.categoryLabelsOrientation === LablePositionEnums.same),\r\n 'categories-block-right': isVertical && !(rucInputData.categoryLabelsOrientation === LablePositionEnums.left || rucInputData.categoryLabelsOrientation === LablePositionEnums.same)\r\n }\">\r\n @for (category of rucInputData.categories; track category) {\r\n <mat-card>\r\n <div class=\"widget-category\">\r\n <div class=\"widget-content\">\r\n <div class=\"widget-icon-box\">\r\n @if (category.icon !== undefined) {\r\n @if (category.icon) {\r\n <div class=\"widget-icon\">\r\n <i class=\"material-icons\" [style.color]=\"category.color\">{{ category.icon }}</i>\r\n </div>\r\n } @else {\r\n <div class=\"category-color\">\r\n <div class=\"color-gradient\"\r\n [style.background]=\"category.color ? 'linear-gradient(to right, ' + category.color + ', ' + category.color + ')' : ''\">\r\n </div>\r\n </div>\r\n }\r\n }\r\n <div class=\"widget-label\">{{category.label}}</div>\r\n </div>\r\n </div>\r\n <div class=\"widget-value\">\r\n <div>{{category.value}}</div>\r\n </div>\r\n </div>\r\n </mat-card>\r\n }\r\n </div>\r\n }\r\n </div>\r\n}\r\n</div>", styles: [".progress-container{position:relative;margin:20px 0}.progress-container.horizontal{width:100%;height:35px}.progress-container.horizontal .progress-bar{width:100%;height:42%}.progress-container.vertical{width:60px;height:320px;margin:0 auto}.progress-container.vertical .progress-bar{width:24%;height:100%}.progress-label-container{position:absolute;z-index:2;width:100%;height:100%;pointer-events:none;display:flex}.progress-label-container.horizontal{justify-content:right;align-items:flex-end;bottom:15px}.progress-label-container.vertical{justify-content:flex-start;align-items:flex-end;left:35px}.progress-label{padding:2px 5px;font-size:12px;white-space:nowrap}.progress-label-container.horizontal .progress-label{margin-top:5px;margin-right:5px}.progress-label-container.vertical .progress-label{transform:rotate(-90deg);transform-origin:bottom left;margin-right:5px}.progress-bar{position:relative;border:1px solid #e0e0e0;border-radius:4px}.progress-bar .hover-label{position:absolute;top:-28px;left:50%;transform:translate(-50%);background-color:#000c;color:#fff;padding:4px 8px;border-radius:4px;font-size:.8em;z-index:5;white-space:nowrap;pointer-events:none}.progress-event-overlay{position:absolute;top:0;left:0;z-index:4}.progress{position:relative;background:#2196f3;transition:width .3s ease,height .3s ease}.progress-bar.horizontal .progress{width:100%;height:100%}.progress-bar.vertical .progress{width:100%;height:0}.icons-container{position:absolute;display:flex;justify-content:space-between;width:100%;height:100%;align-items:center}.icons-container i{position:absolute;font-size:1.2em;color:#fff}.start-icon{left:0}.end-icon{right:0}.above-threshold{color:gold}.categories-container{width:100%;box-sizing:border-box}.categories{display:flex;flex-direction:row;flex-wrap:wrap;gap:1px}.categories-block-top,.categories-block-bottom,.categories-block-left,.categories-block-right{position:absolute;z-index:1}.categories-block-top{bottom:100%;left:0;padding-bottom:8px}.categories-block-bottom{top:100%;left:0;padding-top:10px}.categories-block-left{right:100%;top:0;padding-right:8px;width:200px}.categories-block-left .categories{flex-direction:inherit;align-items:flex-start;gap:0px}.categories-block-right{left:100%;top:0;padding-left:8px;width:200px}.categories-block-right .categories{flex-direction:inherit;align-items:flex-start;gap:0px}.category{display:flex;align-items:center;gap:6px;padding:8px;border-radius:4px}.category-label{font-weight:500}.category-value{font-size:.9em}.category-color{width:10px;height:10px;border-radius:50%;overflow:hidden;flex-shrink:0}.category-icon-wrapper{display:flex;align-items:center;justify-content:center;width:100%;height:100%}.color-gradient{width:100%;height:100%}.categories.widget-style{display:flex;flex-wrap:wrap;gap:10px;justify-content:flex-start;align-items:flex-start;margin:10px 0}.categories.widget-style .widget-category{width:calc(25% - 7.5px);min-width:159px;box-sizing:border-box;flex-shrink:0;flex-grow:0}@media (max-width: 1200px){.categories.widget-style .widget-category{width:calc(33.33% - 6.66px)}}@media (max-width: 768px){.categories.widget-style .widget-category{width:calc(50% - 5px)}}@media (max-width: 480px){.categories.widget-style .widget-category{width:100%}}.categories-block-left,.categories-block-right{flex-direction:inherit;align-items:flex-start;gap:10px}.categories-block-left .widget-category,.categories-block-right .widget-category{width:100%;max-width:none}.widget-category{padding:10px 15px}.widget-content{display:flex;width:100%;align-items:center;margin:0}.widget-icon{border:1px solid #ddd;border-radius:10px;width:35px;height:35px;line-height:45px;text-align:center;background-color:#fdfdfd}.widget-content .category-color{margin-right:35px}.widget-icon,.widget-color{margin-right:8px;flex-shrink:0}.widget-color{width:24px;height:24px;border-radius:50%}.widget-label{flex-grow:1;text-align:left;display:block}.widget-value{font-weight:700;flex-shrink:0;margin-left:45px;text-align:left;margin-top:5px}.widget-icon-box{display:flex;align-items:center}\n"] }]
222
- }], propDecorators: { rucInputData: [{
223
- type: Input
224
- }], customTheme: [{
225
- type: Input
226
- }] } });
227
-
228
- /**
229
- * Generated bundle index. Do not edit.
230
- */
231
-
232
- export { CategoryConfig, MeteredBarConfig, RuclibMeteredProgressBarComponent };
233
- //# sourceMappingURL=ruc-lib-metered-progress-bar.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ruc-lib-metered-progress-bar.mjs","sources":["../../src/lib/model/metered-bar.config.ts","../../src/lib/enums/lable-position.enum.ts","../../src/lib/metered-progress-bar/ruclib-metered-progress-bar.component.ts","../../src/lib/metered-progress-bar/ruclib-metered-progress-bar.component.html","../../src/ruc-lib-metered-progress-bar.ts"],"sourcesContent":["export class MeteredBarConfig {\r\n min!: number;\r\n max!: number;\r\n orientation!: string;\r\n barLabels!: boolean;\r\n barStyle?: 'solid' | 'stripe' | 'circle' | 'rectangle';\r\n categoryLabelsOrientation!: string;\r\n categoryLabelStyle?: string;\r\n showCategoryLabels?: boolean;\r\n categories!: CategoryConfig[];\r\n unitType?: string\r\n}\r\n\r\nexport class CategoryConfig {\r\n label!: string;\r\n color!: string;\r\n value!: number;\r\n icon?: string;\r\n handler?: (event?: any) => void;\r\n}\r\n","export enum LablePositionEnums {\r\n left = \"left\",\r\n right = \"right\",\r\n same = \"same\",\r\n top = \"top\",\r\n bottom = 'bottom'\r\n}\r\n","import { Component, Input } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { CategoryConfig, MeteredBarConfig } from '../model/metered-bar.config';\r\nimport { LablePositionEnums } from '../enums/lable-position.enum';\r\nimport { MatIconModule } from '@angular/material/icon';\r\nimport { MatCardModule } from '@angular/material/card';\r\n\r\n@Component({\r\n selector: 'uxp-metered-progress-bar',\r\n imports: [CommonModule, MatIconModule, MatCardModule],\r\n templateUrl: './ruclib-metered-progress-bar.component.html',\r\n styleUrl: './ruclib-metered-progress-bar.component.scss'\r\n})\r\nexport class RuclibMeteredProgressBarComponent {\r\n @Input() rucInputData!: MeteredBarConfig;\r\n @Input() customTheme!: string;\r\n hoveredCategoryDetail: {\r\n category: CategoryConfig;\r\n percentageText: string;\r\n } | null = null;\r\n hoverLabelStyle: {\r\n left: string;\r\n top: string;\r\n display: string;\r\n transform: string;\r\n } = {\r\n left: '0px',\r\n top: '-28px',\r\n display: 'none',\r\n transform: 'translateX(-50%)',\r\n };\r\n progressPercentage = 0;\r\n /**\r\n * Calculates the total value of all categories.\r\n * @returns The sum of all category values.\r\n */\r\n get totalValue(): number {\r\n return this.rucInputData.categories.reduce(\r\n (sum, category) => sum + category.value,\r\n 0\r\n );\r\n }\r\n\r\n /**\r\n * Calculates the overall progress percentage of the bar based on total value, min, and max.\r\n * @returns The progress as a percentage (0-100).\r\n */\r\n get progress(): number {\r\n return (\r\n ((this.totalValue - this.rucInputData.min) /\r\n (this.rucInputData.max - this.rucInputData.min)) *\r\n 100\r\n );\r\n }\r\n\r\n /**\r\n * Determines if the progress bar is oriented vertically.\r\n * @returns True if the orientation is 'vertical', false otherwise.\r\n */\r\n get isVertical(): boolean {\r\n return this.rucInputData.orientation === 'vertical';\r\n }\r\n\r\n /**\r\n * Generates the CSS linear-gradient string for the progress bar.\r\n * The gradient is composed of segments based on category values and colors.\r\n * If no categories or total value is zero, it returns a transparent gradient.\r\n * @returns A CSS linear-gradient string.\r\n */\r\n get progressStyles(): { [key: string]: string } {\r\n const direction = this.isVertical ? 'to bottom' : 'to right';\r\n\r\n if (!this.rucInputData || !this.rucInputData.categories) {\r\n return { background: 'transparent' };\r\n }\r\n\r\n const total = this.totalValue;\r\n const colorStops: string[] = [];\r\n let cumulativePercentage = 0;\r\n\r\n if (total > 0) {\r\n this.rucInputData.categories.forEach((category) => {\r\n if (category.value <= 0) return; // Skip categories with zero or negative contribution\r\n\r\n const segmentPercentage = (category.value / total) * 100;\r\n const color = category.color;\r\n\r\n // Add start of the segment using the previous cumulative percentage\r\n colorStops.push(`${color} ${cumulativePercentage}%`);\r\n\r\n // Update cumulative percentage for the end of this segment\r\n cumulativePercentage += segmentPercentage;\r\n\r\n // Add end of the segment\r\n // Use Math.min to cap at 100% in case of floating point overshoot on the last segment\r\n colorStops.push(`${color} ${Math.min(cumulativePercentage, 100)}%`);\r\n });\r\n }\r\n\r\n if (colorStops.length === 0) {\r\n return { background: 'transparent' };\r\n }\r\n\r\n const baseGradient = `linear-gradient(${direction}, ${colorStops.join(\r\n ', '\r\n )})`;\r\n const styles: { [key: string]: string } = {};\r\n const barStyle = this.rucInputData?.barStyle;\r\n\r\n switch (barStyle) {\r\n case 'stripe':\r\n // This uses multiple backgrounds for an overlay effect, as requested.\r\n styles[\r\n 'background'\r\n ] = `repeating-linear-gradient(-45deg, transparent, transparent 5px, rgba(0, 0, 0, 0.1) 5px, rgba(0, 0, 0, 0.1) 10px), ${baseGradient}`;\r\n break;\r\n case 'circle': {\r\n // This uses a mask. The background is the color, the mask cuts out the shape.\r\n styles['background'] = baseGradient;\r\n // A repeating pattern of circles. Each circle has a diameter of 8px, with a 4px gap.\r\n const circleMask =\r\n 'radial-gradient(circle, black 4px, transparent 4px) 0 0 / 12px 12px';\r\n styles['-webkit-mask'] = circleMask;\r\n styles['mask'] = circleMask;\r\n break;\r\n }\r\n case 'rectangle': {\r\n styles['background'] = baseGradient;\r\n // For vertical bar, create horizontal rectangles (0deg). For horizontal bar, create vertical rectangles (90deg).\r\n const rectDirection = this.isVertical ? '0deg' : '90deg';\r\n // A repeating pattern of bars. Each bar is 6px wide with a 6px gap.\r\n const rectangleMask = `repeating-linear-gradient(${rectDirection}, black, black 6px, transparent 6px, transparent 12px)`;\r\n styles['-webkit-mask'] = rectangleMask;\r\n styles['mask'] = rectangleMask;\r\n break;\r\n }\r\n default: // 'solid' or undefined\r\n styles['background'] = baseGradient;\r\n break;\r\n }\r\n return styles;\r\n }\r\n /**\r\n * Handles mouse movement over the progress bar to display category-specific hover details.\r\n * It calculates the hovered segment based on mouse position and updates the hover label.\r\n * @param event The MouseEvent object.\r\n */\r\n onProgressMouseMove(event: MouseEvent): void {\r\n const progressBarElement = event.target as HTMLElement;\r\n let currentCumulativeGradientPct = 0;\r\n let foundCategoryForHover: CategoryConfig | null = null;\r\n let hoverPercentage_onFilledBar = 0;\r\n let mousePositionWithinProgressDiv = 0;\r\n\r\n if (this.isVertical) {\r\n mousePositionWithinProgressDiv = event.offsetY; // Y position within the .progress div\r\n const filledHeightPx = progressBarElement.offsetHeight;\r\n if (filledHeightPx <= 0) {\r\n // Avoid division by zero if element has no height\r\n this.onProgressMouseLeave();\r\n return;\r\n }\r\n hoverPercentage_onFilledBar =\r\n (mousePositionWithinProgressDiv / filledHeightPx) * 100;\r\n } else {\r\n // Horizontal\r\n mousePositionWithinProgressDiv = event.offsetX; // X position within the .progress div\r\n const filledWidthPx = progressBarElement.offsetWidth;\r\n if (filledWidthPx <= 0) {\r\n // Avoid division by zero if element has no width\r\n this.onProgressMouseLeave();\r\n return;\r\n }\r\n hoverPercentage_onFilledBar =\r\n (mousePositionWithinProgressDiv / filledWidthPx) * 100;\r\n }\r\n\r\n if (this.totalValue > 0) {\r\n for (const category of this.rucInputData.categories) {\r\n if (category.value <= 0) continue; // Skip categories with zero or negative contribution\r\n\r\n const segmentGradientPct = (category.value / this.totalValue) * 100;\r\n const segmentStartGradientPct = currentCumulativeGradientPct;\r\n const segmentEndGradientPct =\r\n currentCumulativeGradientPct + segmentGradientPct;\r\n\r\n // Ensure hoverPercentage is within the segment, handling potential floating point inaccuracies for the last segment\r\n if (\r\n hoverPercentage_onFilledBar >= segmentStartGradientPct && // Check if mouse is within or at the start of the segment\r\n (hoverPercentage_onFilledBar < segmentEndGradientPct ||\r\n (segmentEndGradientPct >= 99.99 &&\r\n hoverPercentage_onFilledBar <= 100.01))\r\n ) {\r\n // Tolerate slight overshoot for last segment\r\n foundCategoryForHover = category;\r\n break;\r\n }\r\n currentCumulativeGradientPct = segmentEndGradientPct;\r\n }\r\n }\r\n\r\n if (foundCategoryForHover) {\r\n const percentageOfMax =\r\n (foundCategoryForHover.value / this.rucInputData.max) * 100; // Calculate percentage relative to max value\r\n this.hoveredCategoryDetail = {\r\n category: foundCategoryForHover,\r\n percentageText: percentageOfMax.toFixed(0) + '%',\r\n };\r\n if (this.isVertical) {\r\n this.hoverLabelStyle = {\r\n left: 'calc(100% + 5px)', // Position to the right of the vertical bar\r\n top: mousePositionWithinProgressDiv + 'px',\r\n display: 'block',\r\n transform: 'translateY(-50%)', // Vertically center label on mouse Y\r\n };\r\n } else {\r\n this.hoverLabelStyle = {\r\n left: mousePositionWithinProgressDiv + 'px',\r\n top: '-28px', // Position above horizontal bar\r\n display: 'block',\r\n transform: 'translateX(-50%)', // Horizontally center label on mouse X\r\n };\r\n }\r\n } else {\r\n this.hoveredCategoryDetail = null;\r\n this.hoverLabelStyle = { ...this.hoverLabelStyle, display: 'none' };\r\n }\r\n }\r\n\r\n /**\r\n * Hides the hover label when the mouse leaves the progress bar.\r\n */\r\n onProgressMouseLeave(): void {\r\n this.hoveredCategoryDetail = null;\r\n this.hoverLabelStyle = { ...this.hoverLabelStyle, display: 'none' };\r\n }\r\n /**\r\n * get the label position string value\r\n */\r\n public get LablePositionEnums(): typeof LablePositionEnums {\r\n return LablePositionEnums;\r\n }\r\n}\r\n","<div class=\"progress-container\" class={{customTheme}} [class.vertical]=\"isVertical\" [class.horizontal]=\"!isVertical\">\r\n <div class=\"progress-bar\">\r\n <!-- Removed (mouseenter) and (mouseleave) from progress-bar if only category hover is needed -->\r\n @if (rucInputData.barLabels) {\r\n <div class=\"progress-label-container {{rucInputData.orientation}}\">\r\n <p class=\"progress-label\">{{progress | number:'1.0-0'}}% of {{rucInputData.max}} {{rucInputData.unitType}}\r\n Used</p>\r\n </div>\r\n }\r\n <!-- <mat-progress-bar> -->\r\n <div class=\"progress\" [style.width]=\"isVertical ? '100%' : progress + '%'\"\r\n [style.height]=\"isVertical ? progress + '%' : '100%'\"\r\n [style.transition]=\"rucInputData.orientation === 'vertical' ? 'height 0.3s ease' : 'width 0.3s ease'\"\r\n [ngStyle]=\"progressStyles\">\r\n <!-- This div is now only for displaying the colored bar -->\r\n </div>\r\n <!-- </mat-progress-bar> -->\r\n <!-- The hover label is now a sibling to .progress, positioned absolutely within .progress-bar -->\r\n @if (hoveredCategoryDetail) {\r\n <div class=\"hover-label\" [ngStyle]=\"hoverLabelStyle\">\r\n {{hoveredCategoryDetail.category.label}}: {{hoveredCategoryDetail.percentageText}}\r\n </div>\r\n }\r\n <!-- This overlay is now a sibling to .progress, sized to match it, to reliably capture mouse events -->\r\n <div class=\"progress-event-overlay\" [style.width]=\"isVertical ? '100%' : progress + '%'\"\r\n [style.height]=\"isVertical ? progress + '%' : '100%'\" (mousemove)=\"onProgressMouseMove($event)\"\r\n (mouseleave)=\"onProgressMouseLeave()\"></div>\r\n</div>\r\n@if (rucInputData.categories.length > 0) {\r\n <div class=\"categories-container\">\r\n @if (rucInputData.showCategoryLabels && rucInputData.categoryLabelStyle === 'basic') {\r\n<div [ngClass]=\"{\r\n 'categories-block-top': !isVertical && (rucInputData.categoryLabelsOrientation === 'top' || rucInputData.categoryLabelsOrientation === 'same'),\r\n 'categories-block-left': isVertical && (rucInputData.categoryLabelsOrientation === 'left' || rucInputData.categoryLabelsOrientation === 'same'),\r\n 'categories-block-right': isVertical && !(rucInputData.categoryLabelsOrientation === 'left' || rucInputData.categoryLabelsOrientation === 'same')\r\n }\" class=\"categories\">\r\n @for (category of rucInputData.categories; track category) {\r\n <div class=\"category\" [style.color]=\"category.color\">\r\n @if (category.icon !== undefined) {\r\n @if (category.icon) {\r\n <div class=\"category-icon-wrapper\">\r\n <i class=\"material-icons\" [style.color]=\"category.color\">{{ category.icon }}</i>\r\n </div>\r\n } @else {\r\n <div class=\"category-color\">\r\n <div class=\"color-gradient\"\r\n [style.background]=\"category.color ? 'linear-gradient(to right, ' + category.color + ', ' + category.color + ')' : ''\">\r\n </div>\r\n </div>\r\n }\r\n }\r\n <span class=\"category-label\">{{category.label}}</span>\r\n <p class=\"category-value\">({{(category.value / rucInputData.max * 100) | number:'1.0-0' }}%)</p>\r\n </div>\r\n }\r\n </div>\r\n }\r\n @if (rucInputData.showCategoryLabels && rucInputData.categoryLabelStyle === 'widget') {\r\n <div\r\n class=\"categories widget-style\" [ngClass]=\"{\r\n 'categories-block-top': !isVertical && (rucInputData.categoryLabelsOrientation === LablePositionEnums.top || rucInputData.categoryLabelsOrientation === LablePositionEnums.same),\r\n 'categories-block-left': isVertical && (rucInputData.categoryLabelsOrientation === LablePositionEnums.left || rucInputData.categoryLabelsOrientation === LablePositionEnums.same),\r\n 'categories-block-right': isVertical && !(rucInputData.categoryLabelsOrientation === LablePositionEnums.left || rucInputData.categoryLabelsOrientation === LablePositionEnums.same)\r\n }\">\r\n @for (category of rucInputData.categories; track category) {\r\n <mat-card>\r\n <div class=\"widget-category\">\r\n <div class=\"widget-content\">\r\n <div class=\"widget-icon-box\">\r\n @if (category.icon !== undefined) {\r\n @if (category.icon) {\r\n <div class=\"widget-icon\">\r\n <i class=\"material-icons\" [style.color]=\"category.color\">{{ category.icon }}</i>\r\n </div>\r\n } @else {\r\n <div class=\"category-color\">\r\n <div class=\"color-gradient\"\r\n [style.background]=\"category.color ? 'linear-gradient(to right, ' + category.color + ', ' + category.color + ')' : ''\">\r\n </div>\r\n </div>\r\n }\r\n }\r\n <div class=\"widget-label\">{{category.label}}</div>\r\n </div>\r\n </div>\r\n <div class=\"widget-value\">\r\n <div>{{category.value}}</div>\r\n </div>\r\n </div>\r\n </mat-card>\r\n }\r\n </div>\r\n }\r\n </div>\r\n}\r\n</div>","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}