@ruc-lib/metered-progress-bar 2.0.1 → 3.1.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.
- package/README.md +58 -27
- package/fesm2022/ruc-lib-metered-progress-bar.mjs +233 -0
- package/fesm2022/ruc-lib-metered-progress-bar.mjs.map +1 -0
- package/index.d.ts +87 -3
- package/package.json +6 -18
- package/esm2020/index.mjs +0 -4
- package/esm2020/lib/enums/lable-position.enum.mjs +0 -9
- package/esm2020/lib/model/metered-bar.config.mjs +0 -5
- package/esm2020/lib/ruc-metered-progress-bar/ruc-metered-progress-bar.component.mjs +0 -194
- package/esm2020/lib/ruclib-metered-progress-bar.module.mjs +0 -20
- package/esm2020/ruc-lib-metered-progress-bar.mjs +0 -5
- package/fesm2015/ruc-lib-metered-progress-bar.mjs +0 -231
- package/fesm2015/ruc-lib-metered-progress-bar.mjs.map +0 -1
- package/fesm2020/ruc-lib-metered-progress-bar.mjs +0 -230
- package/fesm2020/ruc-lib-metered-progress-bar.mjs.map +0 -1
- package/lib/enums/lable-position.enum.d.ts +0 -7
- package/lib/model/metered-bar.config.d.ts +0 -19
- package/lib/ruc-metered-progress-bar/ruc-metered-progress-bar.component.d.ts +0 -58
- package/lib/ruclib-metered-progress-bar.module.d.ts +0 -10
package/README.md
CHANGED
|
@@ -17,38 +17,46 @@ If you only need the Metered Progress Bar component:
|
|
|
17
17
|
npm install @ruc-lib/metered-progress-bar
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
-
## Usage
|
|
21
20
|
|
|
22
|
-
|
|
23
|
-
In your Angular module file (e.g., `app.module.ts`), import the `RucMeteredProgressBarModule`:
|
|
21
|
+
# Version Compatibility
|
|
24
22
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
23
|
+
Please ensure you install the correct version of `@ruc-lib/metered-progress-bar` based on your Angular version.
|
|
24
|
+
|
|
25
|
+
| Angular Version | Compatible `@ruc-lib/metered-progress-bar` Version |
|
|
26
|
+
|--------------------|--------------------------------------------------------|
|
|
27
|
+
| 15.x.x | `npm install @ruc-lib/metered-progress-bar@^3.0.0` |
|
|
28
|
+
| 16.x.x | `npm install @ruc-lib/metered-progress-bar@^3.0.0` |
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
## Usage
|
|
32
|
+
|
|
33
|
+
### 1. Import the Component
|
|
34
|
+
In your Angular component file (e.g., `app.component.ts`), import the `RuclibMeteredProgressBarComponent`:
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
import { Component } from '@angular/core';
|
|
38
|
+
|
|
39
|
+
// For Complete Library
|
|
40
|
+
import { RuclibMeteredProgressBarComponent } from '@uxpractice/ruc-lib/metered-progress-bar';
|
|
41
|
+
|
|
42
|
+
// For Individual Package
|
|
43
|
+
import { RuclibMeteredProgressBarComponent } from '@ruc-lib/metered-progress-bar';
|
|
44
|
+
|
|
45
|
+
@Component({
|
|
46
|
+
selector: 'app-root',
|
|
47
|
+
imports: [RuclibMeteredProgressBarComponent],
|
|
48
|
+
templateUrl: './app.component.html',
|
|
49
|
+
})
|
|
50
|
+
export class AppComponent {
|
|
51
|
+
// Component code here
|
|
52
|
+
}
|
|
45
53
|
```
|
|
46
54
|
|
|
47
55
|
### 2. Use the Component
|
|
48
|
-
In your component's template, use the `<uxp-
|
|
56
|
+
In your component's template, use the `<uxp-ruclib-metered-progress-bar>` selector and pass the configuration object to the `rucInputData` input.
|
|
49
57
|
|
|
50
58
|
```html
|
|
51
|
-
<uxp-
|
|
59
|
+
<uxp-ruclib-metered-progress-bar [rucInputData]="meteredBarConfig"></uxp-ruclib-metered-progress-bar>
|
|
52
60
|
```
|
|
53
61
|
|
|
54
62
|
## API Reference
|
|
@@ -94,7 +102,13 @@ Here's an example of how to configure the Metered Progress Bar in your component
|
|
|
94
102
|
|
|
95
103
|
```typescript
|
|
96
104
|
import { Component } from '@angular/core';
|
|
97
|
-
|
|
105
|
+
|
|
106
|
+
// For Complete Library
|
|
107
|
+
import { MeteredBarConfig } from '@uxpractice/ruc-lib/metered-progress-bar';
|
|
108
|
+
|
|
109
|
+
// For Individual Package
|
|
110
|
+
import { MeteredBarConfig } from '@ruc-lib/metered-progress-bar';
|
|
111
|
+
|
|
98
112
|
|
|
99
113
|
@Component({
|
|
100
114
|
selector: 'app-root',
|
|
@@ -121,10 +135,27 @@ export class AppComponent {
|
|
|
121
135
|
}
|
|
122
136
|
```
|
|
123
137
|
|
|
138
|
+
> ⚠️ **IMPORTANT: Custom Theme Usage in Angular Material**
|
|
139
|
+
|
|
140
|
+
When implementing **custom themes**, such as:
|
|
141
|
+
|
|
142
|
+
```scss
|
|
143
|
+
.custom-theme-1 {
|
|
144
|
+
@include angular-material-theme($custom-theme);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// You must also include the typography mixin to ensure text styles are applied correctly as shown below:
|
|
148
|
+
.custom-theme-1 {
|
|
149
|
+
@include angular-material-theme($custom-theme);
|
|
150
|
+
@include mat.typography-level($theme-custom-typography-name, body-1);
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
|
|
124
155
|
## Contribution
|
|
125
156
|
|
|
126
157
|
Contributions are welcome! Feel free to open issues or pull requests for any enhancements or fixes.
|
|
127
158
|
|
|
128
159
|
## Acknowledgements
|
|
129
160
|
|
|
130
|
-
Thank you for choosing the Metered Progress Bar component. If you have any feedback or suggestions, please let us know!
|
|
161
|
+
Thank you for choosing the Metered Progress Bar component. If you have any feedback or suggestions, please let us know!
|
|
@@ -0,0 +1,233 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
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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"}
|
package/index.d.ts
CHANGED
|
@@ -1,3 +1,87 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
|
|
3
|
+
declare class MeteredBarConfig {
|
|
4
|
+
min: number;
|
|
5
|
+
max: number;
|
|
6
|
+
orientation: string;
|
|
7
|
+
barLabels: boolean;
|
|
8
|
+
barStyle?: 'solid' | 'stripe' | 'circle' | 'rectangle';
|
|
9
|
+
categoryLabelsOrientation: string;
|
|
10
|
+
categoryLabelStyle?: string;
|
|
11
|
+
showCategoryLabels?: boolean;
|
|
12
|
+
categories: CategoryConfig[];
|
|
13
|
+
unitType?: string;
|
|
14
|
+
}
|
|
15
|
+
declare class CategoryConfig {
|
|
16
|
+
label: string;
|
|
17
|
+
color: string;
|
|
18
|
+
value: number;
|
|
19
|
+
icon?: string;
|
|
20
|
+
handler?: (event?: any) => void;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
declare enum LablePositionEnums {
|
|
24
|
+
left = "left",
|
|
25
|
+
right = "right",
|
|
26
|
+
same = "same",
|
|
27
|
+
top = "top",
|
|
28
|
+
bottom = "bottom"
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
declare class RuclibMeteredProgressBarComponent {
|
|
32
|
+
rucInputData: MeteredBarConfig;
|
|
33
|
+
customTheme: string;
|
|
34
|
+
hoveredCategoryDetail: {
|
|
35
|
+
category: CategoryConfig;
|
|
36
|
+
percentageText: string;
|
|
37
|
+
} | null;
|
|
38
|
+
hoverLabelStyle: {
|
|
39
|
+
left: string;
|
|
40
|
+
top: string;
|
|
41
|
+
display: string;
|
|
42
|
+
transform: string;
|
|
43
|
+
};
|
|
44
|
+
progressPercentage: number;
|
|
45
|
+
/**
|
|
46
|
+
* Calculates the total value of all categories.
|
|
47
|
+
* @returns The sum of all category values.
|
|
48
|
+
*/
|
|
49
|
+
get totalValue(): number;
|
|
50
|
+
/**
|
|
51
|
+
* Calculates the overall progress percentage of the bar based on total value, min, and max.
|
|
52
|
+
* @returns The progress as a percentage (0-100).
|
|
53
|
+
*/
|
|
54
|
+
get progress(): number;
|
|
55
|
+
/**
|
|
56
|
+
* Determines if the progress bar is oriented vertically.
|
|
57
|
+
* @returns True if the orientation is 'vertical', false otherwise.
|
|
58
|
+
*/
|
|
59
|
+
get isVertical(): boolean;
|
|
60
|
+
/**
|
|
61
|
+
* Generates the CSS linear-gradient string for the progress bar.
|
|
62
|
+
* The gradient is composed of segments based on category values and colors.
|
|
63
|
+
* If no categories or total value is zero, it returns a transparent gradient.
|
|
64
|
+
* @returns A CSS linear-gradient string.
|
|
65
|
+
*/
|
|
66
|
+
get progressStyles(): {
|
|
67
|
+
[key: string]: string;
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* Handles mouse movement over the progress bar to display category-specific hover details.
|
|
71
|
+
* It calculates the hovered segment based on mouse position and updates the hover label.
|
|
72
|
+
* @param event The MouseEvent object.
|
|
73
|
+
*/
|
|
74
|
+
onProgressMouseMove(event: MouseEvent): void;
|
|
75
|
+
/**
|
|
76
|
+
* Hides the hover label when the mouse leaves the progress bar.
|
|
77
|
+
*/
|
|
78
|
+
onProgressMouseLeave(): void;
|
|
79
|
+
/**
|
|
80
|
+
* get the label position string value
|
|
81
|
+
*/
|
|
82
|
+
get LablePositionEnums(): typeof LablePositionEnums;
|
|
83
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<RuclibMeteredProgressBarComponent, never>;
|
|
84
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<RuclibMeteredProgressBarComponent, "uxp-metered-progress-bar", never, { "rucInputData": { "alias": "rucInputData"; "required": false; }; "customTheme": { "alias": "customTheme"; "required": false; }; }, {}, never, never, true, never>;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export { CategoryConfig, MeteredBarConfig, RuclibMeteredProgressBarComponent };
|
package/package.json
CHANGED
|
@@ -1,24 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ruc-lib/metered-progress-bar",
|
|
3
|
-
"version": "
|
|
4
|
-
"license": "MIT",
|
|
3
|
+
"version": "3.1.0",
|
|
5
4
|
"peerDependencies": {
|
|
6
|
-
"@angular/common": "^
|
|
7
|
-
"@angular/core": "^
|
|
8
|
-
"@angular/material": "^15.
|
|
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"
|
|
9
8
|
},
|
|
10
9
|
"dependencies": {
|
|
11
10
|
"tslib": "^2.3.0"
|
|
12
11
|
},
|
|
13
|
-
"publishConfig": {
|
|
14
|
-
"access": "public"
|
|
15
|
-
},
|
|
16
12
|
"sideEffects": false,
|
|
17
|
-
"module": "
|
|
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",
|
|
13
|
+
"module": "fesm2022/ruc-lib-metered-progress-bar.mjs",
|
|
22
14
|
"typings": "index.d.ts",
|
|
23
15
|
"exports": {
|
|
24
16
|
"./package.json": {
|
|
@@ -26,11 +18,7 @@
|
|
|
26
18
|
},
|
|
27
19
|
".": {
|
|
28
20
|
"types": "./index.d.ts",
|
|
29
|
-
"
|
|
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"
|
|
21
|
+
"default": "./fesm2022/ruc-lib-metered-progress-bar.mjs"
|
|
34
22
|
}
|
|
35
23
|
}
|
|
36
24
|
}
|
package/esm2020/index.mjs
DELETED
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
export * from './lib/ruclib-metered-progress-bar.module';
|
|
2
|
-
export * from './lib/model/metered-bar.config';
|
|
3
|
-
export * from './lib/ruc-metered-progress-bar/ruc-metered-progress-bar.component';
|
|
4
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsY0FBYywwQ0FBMEMsQ0FBQztBQUN6RCxjQUFjLGdDQUFnQyxDQUFDO0FBQy9DLGNBQWMsbUVBQW1FLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgKiBmcm9tICcuL2xpYi9ydWNsaWItbWV0ZXJlZC1wcm9ncmVzcy1iYXIubW9kdWxlJztcclxuZXhwb3J0ICogZnJvbSAnLi9saWIvbW9kZWwvbWV0ZXJlZC1iYXIuY29uZmlnJztcclxuZXhwb3J0ICogZnJvbSAnLi9saWIvcnVjLW1ldGVyZWQtcHJvZ3Jlc3MtYmFyL3J1Yy1tZXRlcmVkLXByb2dyZXNzLWJhci5jb21wb25lbnQnO1xyXG4iXX0=
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
export var LablePositionEnums;
|
|
2
|
-
(function (LablePositionEnums) {
|
|
3
|
-
LablePositionEnums["left"] = "left";
|
|
4
|
-
LablePositionEnums["right"] = "right";
|
|
5
|
-
LablePositionEnums["same"] = "same";
|
|
6
|
-
LablePositionEnums["top"] = "top";
|
|
7
|
-
LablePositionEnums["bottom"] = "bottom";
|
|
8
|
-
})(LablePositionEnums || (LablePositionEnums = {}));
|
|
9
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGFibGUtcG9zaXRpb24uZW51bS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvZW51bXMvbGFibGUtcG9zaXRpb24uZW51bS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxNQUFNLENBQU4sSUFBWSxrQkFNWDtBQU5ELFdBQVksa0JBQWtCO0lBQzFCLG1DQUFhLENBQUE7SUFDYixxQ0FBZSxDQUFBO0lBQ2YsbUNBQWEsQ0FBQTtJQUNiLGlDQUFXLENBQUE7SUFDWCx1Q0FBaUIsQ0FBQTtBQUNyQixDQUFDLEVBTlcsa0JBQWtCLEtBQWxCLGtCQUFrQixRQU03QiIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBlbnVtIExhYmxlUG9zaXRpb25FbnVtcyB7XHJcbiAgICBsZWZ0ID0gXCJsZWZ0XCIsXHJcbiAgICByaWdodCA9IFwicmlnaHRcIixcclxuICAgIHNhbWUgPSBcInNhbWVcIixcclxuICAgIHRvcCA9IFwidG9wXCIsXHJcbiAgICBib3R0b20gPSAnYm90dG9tJ1xyXG59XHJcbiJdfQ==
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
export class MeteredBarConfig {
|
|
2
|
-
}
|
|
3
|
-
export class CategoryConfig {
|
|
4
|
-
}
|
|
5
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWV0ZXJlZC1iYXIuY29uZmlnLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2xpYi9tb2RlbC9tZXRlcmVkLWJhci5jb25maWcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsTUFBTSxPQUFPLGdCQUFnQjtDQVc1QjtBQUVELE1BQU0sT0FBTyxjQUFjO0NBTTFCIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGNsYXNzIE1ldGVyZWRCYXJDb25maWcge1xyXG4gICAgbWluITogbnVtYmVyO1xyXG4gICAgbWF4ITogbnVtYmVyO1xyXG4gICAgb3JpZW50YXRpb24hOiBzdHJpbmc7XHJcbiAgICBiYXJMYWJlbHMhOiBib29sZWFuO1xyXG4gICAgYmFyU3R5bGU/OiAnc29saWQnIHwgJ3N0cmlwZScgfCAnY2lyY2xlJyB8ICdyZWN0YW5nbGUnO1xyXG4gICAgY2F0ZWdvcnlMYWJlbHNPcmllbnRhdGlvbiE6IHN0cmluZztcclxuICAgIGNhdGVnb3J5TGFiZWxTdHlsZT86IHN0cmluZztcclxuICAgIHNob3dDYXRlZ29yeUxhYmVscz86IGJvb2xlYW47XHJcbiAgICBjYXRlZ29yaWVzITogQ2F0ZWdvcnlDb25maWdbXTtcclxuICAgIHVuaXRUeXBlPzogc3RyaW5nXHJcbn1cclxuXHJcbmV4cG9ydCBjbGFzcyBDYXRlZ29yeUNvbmZpZyB7XHJcbiAgICBsYWJlbCE6IHN0cmluZztcclxuICAgIGNvbG9yITogc3RyaW5nO1xyXG4gICAgdmFsdWUhOiBudW1iZXI7XHJcbiAgICBpY29uPzogc3RyaW5nO1xyXG4gICAgaGFuZGxlcj86IChldmVudD86IGFueSkgPT4gdm9pZDtcclxufVxyXG4iXX0=
|