web-mojo 2.1.1044 → 2.1.1087
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin.cjs.js +1 -1
- package/dist/admin.cjs.js.map +1 -1
- package/dist/admin.es.js +14 -14
- package/dist/admin.es.js.map +1 -1
- package/dist/auth.cjs.js +1 -1
- package/dist/auth.es.js +1 -1
- package/dist/charts.cjs.js +1 -1
- package/dist/charts.cjs.js.map +1 -1
- package/dist/charts.css +319 -0
- package/dist/charts.es.js +555 -3
- package/dist/charts.es.js.map +1 -1
- package/dist/chunks/{ChatView-Bvkdj-lq.js → ChatView-BnC15uoD.js} +2 -2
- package/dist/chunks/{ChatView-Bvkdj-lq.js.map → ChatView-BnC15uoD.js.map} +1 -1
- package/dist/chunks/{ChatView-DBgQzOyI.js → ChatView-D-5lHZ5H.js} +7 -7
- package/dist/chunks/{ChatView-DBgQzOyI.js.map → ChatView-D-5lHZ5H.js.map} +1 -1
- package/dist/chunks/{Collection-DD1_31eh.js → Collection-B64LJ92k.js} +2 -2
- package/dist/chunks/{Collection-DD1_31eh.js.map → Collection-B64LJ92k.js.map} +1 -1
- package/dist/chunks/{Collection-DaTm-2LH.js → Collection-CsAk0UhA.js} +2 -2
- package/dist/chunks/{Collection-DaTm-2LH.js.map → Collection-CsAk0UhA.js.map} +1 -1
- package/dist/chunks/{ContextMenu-snx9Dd1s.js → ContextMenu-CfMAB33c.js} +2 -2
- package/dist/chunks/{ContextMenu-snx9Dd1s.js.map → ContextMenu-CfMAB33c.js.map} +1 -1
- package/dist/chunks/{ContextMenu-hQH_6Pyi.js → ContextMenu-Cvls3QC_.js} +3 -3
- package/dist/chunks/{ContextMenu-hQH_6Pyi.js.map → ContextMenu-Cvls3QC_.js.map} +1 -1
- package/dist/chunks/{DataView-D7j4IWyS.js → DataView-DESqBxT-.js} +2 -2
- package/dist/chunks/{DataView-D7j4IWyS.js.map → DataView-DESqBxT-.js.map} +1 -1
- package/dist/chunks/{DataView-CWejLV3B.js → DataView-QXyfcg2M.js} +2 -2
- package/dist/chunks/{DataView-CWejLV3B.js.map → DataView-QXyfcg2M.js.map} +1 -1
- package/dist/chunks/Dialog-BfXN-fFA.js +2 -0
- package/dist/chunks/Dialog-BfXN-fFA.js.map +1 -0
- package/dist/chunks/{Dialog-BcJG5Vta.js → Dialog-DHUsZ92-.js} +20 -6
- package/dist/chunks/Dialog-DHUsZ92-.js.map +1 -0
- package/dist/chunks/{FormView-BClEkzmE.js → FormView-DGRmcKUG.js} +282 -123
- package/dist/chunks/FormView-DGRmcKUG.js.map +1 -0
- package/dist/chunks/FormView-KGvr68ju.js +3 -0
- package/dist/chunks/FormView-KGvr68ju.js.map +1 -0
- package/dist/chunks/{ListView-BrsQ26R6.js → ListView-BGJG4GYH.js} +3 -3
- package/dist/chunks/{ListView-BrsQ26R6.js.map → ListView-BGJG4GYH.js.map} +1 -1
- package/dist/chunks/{ListView-BRGiITfD.js → ListView-BpGEatee.js} +2 -2
- package/dist/chunks/{ListView-BRGiITfD.js.map → ListView-BpGEatee.js.map} +1 -1
- package/dist/chunks/{MetricsMiniChartWidget-DALWxrzu.js → MetricsMiniChartWidget-BKbFGvXG.js} +4 -4
- package/dist/chunks/{MetricsMiniChartWidget-DALWxrzu.js.map → MetricsMiniChartWidget-BKbFGvXG.js.map} +1 -1
- package/dist/chunks/{MetricsMiniChartWidget-CN1HPnWf.js → MetricsMiniChartWidget-BNdGuSZV.js} +2 -2
- package/dist/chunks/{MetricsMiniChartWidget-CN1HPnWf.js.map → MetricsMiniChartWidget-BNdGuSZV.js.map} +1 -1
- package/dist/chunks/{PDFViewer-CgdSGU1n.js → PDFViewer-BIBNhuWY.js} +3 -3
- package/dist/chunks/{PDFViewer-CgdSGU1n.js.map → PDFViewer-BIBNhuWY.js.map} +1 -1
- package/dist/chunks/{PDFViewer-DtJIlPXi.js → PDFViewer-nZAQQScE.js} +2 -2
- package/dist/chunks/{PDFViewer-DtJIlPXi.js.map → PDFViewer-nZAQQScE.js.map} +1 -1
- package/dist/chunks/Rest-BpDyhFfG.js +2 -0
- package/dist/chunks/Rest-BpDyhFfG.js.map +1 -0
- package/dist/chunks/{Rest-CS4jRCAs.js → Rest-DpbPbmra.js} +96 -5
- package/dist/chunks/Rest-DpbPbmra.js.map +1 -0
- package/dist/chunks/{TokenManager-DIEFCQ3B.js → TokenManager-BWc_pRpg.js} +2 -2
- package/dist/chunks/{TokenManager-DIEFCQ3B.js.map → TokenManager-BWc_pRpg.js.map} +1 -1
- package/dist/chunks/{TokenManager-BanwFrq7.js → TokenManager-N3e5wDu1.js} +5 -5
- package/dist/chunks/{TokenManager-BanwFrq7.js.map → TokenManager-N3e5wDu1.js.map} +1 -1
- package/dist/chunks/{WebSocketClient-D-5DJoMX.js → WebSocketClient-DghNkEyO.js} +2 -2
- package/dist/chunks/{WebSocketClient-D-5DJoMX.js.map → WebSocketClient-DghNkEyO.js.map} +1 -1
- package/dist/chunks/{WebSocketClient-DzcqAmho.js → WebSocketClient-E08hfP5f.js} +2 -2
- package/dist/chunks/{WebSocketClient-DzcqAmho.js.map → WebSocketClient-E08hfP5f.js.map} +1 -1
- package/dist/chunks/{version-WMgX72-y.js → version-CKPqwcQJ.js} +2 -2
- package/dist/chunks/{version-WMgX72-y.js.map → version-CKPqwcQJ.js.map} +1 -1
- package/dist/chunks/{version-BaFu2yii.js → version-Dtwh-YkD.js} +4 -4
- package/dist/chunks/{version-BaFu2yii.js.map → version-Dtwh-YkD.js.map} +1 -1
- package/dist/css/web-mojo.css +1 -1
- package/dist/docit.cjs.js +1 -1
- package/dist/docit.es.js +6 -6
- package/dist/index.cjs.js +1 -1
- package/dist/index.es.js +15 -15
- package/dist/lightbox.cjs.js +1 -1
- package/dist/lightbox.es.js +5 -5
- package/dist/map.cjs.js +1 -1
- package/dist/map.cjs.js.map +1 -1
- package/dist/map.es.js +82 -3
- package/dist/map.es.js.map +1 -1
- package/dist/timeline.cjs.js +1 -1
- package/dist/timeline.es.js +4 -4
- package/package.json +1 -1
- package/dist/chunks/Dialog-7T8ENHYD.js +0 -2
- package/dist/chunks/Dialog-7T8ENHYD.js.map +0 -1
- package/dist/chunks/Dialog-BcJG5Vta.js.map +0 -1
- package/dist/chunks/FormView-BClEkzmE.js.map +0 -1
- package/dist/chunks/FormView-nulck4nL.js +0 -3
- package/dist/chunks/FormView-nulck4nL.js.map +0 -1
- package/dist/chunks/Rest-BNYqGlnP.js +0 -2
- package/dist/chunks/Rest-BNYqGlnP.js.map +0 -1
- package/dist/chunks/Rest-CS4jRCAs.js.map +0 -1
package/dist/charts.es.js
CHANGED
|
@@ -1,9 +1,561 @@
|
|
|
1
|
-
import { B, M, b, c, a, P, S } from "./chunks/MetricsMiniChartWidget-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { B, M, b, c, a, P, S } from "./chunks/MetricsMiniChartWidget-BKbFGvXG.js";
|
|
2
|
+
import { V as View, d as dataFormatter } from "./chunks/Rest-DpbPbmra.js";
|
|
3
|
+
import { W } from "./chunks/Dialog-DHUsZ92-.js";
|
|
4
|
+
import { B as B2, a as a2, V, b as b2, c as c2, d } from "./chunks/version-Dtwh-YkD.js";
|
|
5
|
+
class CircularProgress extends View {
|
|
6
|
+
constructor(options = {}) {
|
|
7
|
+
super({
|
|
8
|
+
className: `circular-progress ${options.className || ""}`,
|
|
9
|
+
...options
|
|
10
|
+
});
|
|
11
|
+
this.SIZE_PRESETS = {
|
|
12
|
+
"xs": 40,
|
|
13
|
+
"sm": 60,
|
|
14
|
+
"md": 80,
|
|
15
|
+
"lg": 120,
|
|
16
|
+
"xl": 180
|
|
17
|
+
};
|
|
18
|
+
this.STROKE_PRESETS = {
|
|
19
|
+
"xs": 4,
|
|
20
|
+
"sm": 6,
|
|
21
|
+
"md": 8,
|
|
22
|
+
"lg": 12,
|
|
23
|
+
"xl": 16
|
|
24
|
+
};
|
|
25
|
+
this.value = options.value !== void 0 ? options.value : 0;
|
|
26
|
+
this.min = options.min !== void 0 ? options.min : 0;
|
|
27
|
+
this.max = options.max !== void 0 ? options.max : 100;
|
|
28
|
+
this.sizePreset = typeof options.size === "string" && this.SIZE_PRESETS[options.size] ? options.size : null;
|
|
29
|
+
this.size = this.resolveSize(options.size !== void 0 ? options.size : "md");
|
|
30
|
+
this.strokeWidth = options.strokeWidth === "auto" || options.strokeWidth === void 0 ? this.getAutoStrokeWidth(options.size) : options.strokeWidth;
|
|
31
|
+
this.theme = options.theme || "basic";
|
|
32
|
+
this.variant = options.variant || "default";
|
|
33
|
+
this.color = options.color;
|
|
34
|
+
this.trackColor = options.trackColor;
|
|
35
|
+
this.textColor = options.textColor;
|
|
36
|
+
this.gradientColors = options.gradientColors || null;
|
|
37
|
+
this.applyTheme();
|
|
38
|
+
this.applyVariant();
|
|
39
|
+
this.rotation = options.rotation !== void 0 ? options.rotation : -90;
|
|
40
|
+
this.gap = options.gap || 0;
|
|
41
|
+
this.showValue = options.showValue !== false;
|
|
42
|
+
this.valueFormat = options.valueFormat || "percentage";
|
|
43
|
+
this.valueFormatter = options.valueFormatter || null;
|
|
44
|
+
this.label = options.label || null;
|
|
45
|
+
this.labelHtml = options.labelHtml || null;
|
|
46
|
+
this.icon = options.icon || null;
|
|
47
|
+
this.animate = options.animate !== false;
|
|
48
|
+
this.animationDuration = options.animationDuration || 600;
|
|
49
|
+
this.animationEasing = options.animationEasing || "ease-out";
|
|
50
|
+
this.rounded = options.rounded !== false;
|
|
51
|
+
this.shadow = options.shadow || false;
|
|
52
|
+
this.clickable = options.clickable || false;
|
|
53
|
+
this.tooltip = options.tooltip || null;
|
|
54
|
+
this.tooltipPlacement = options.tooltipPlacement || "top";
|
|
55
|
+
this.segments = options.segments || null;
|
|
56
|
+
this.segmentGap = options.segmentGap || 2;
|
|
57
|
+
this.dataFormatter = dataFormatter;
|
|
58
|
+
this.svg = null;
|
|
59
|
+
this.centerElement = null;
|
|
60
|
+
this.popover = null;
|
|
61
|
+
this.gradientId = `gradient-${Math.random().toString(36).substr(2, 9)}`;
|
|
62
|
+
}
|
|
63
|
+
resolveSize(size) {
|
|
64
|
+
if (typeof size === "string" && this.SIZE_PRESETS[size]) {
|
|
65
|
+
return this.SIZE_PRESETS[size];
|
|
66
|
+
}
|
|
67
|
+
return typeof size === "number" ? size : this.SIZE_PRESETS.md;
|
|
68
|
+
}
|
|
69
|
+
getAutoStrokeWidth(size) {
|
|
70
|
+
if (typeof size === "string" && this.STROKE_PRESETS[size]) {
|
|
71
|
+
return this.STROKE_PRESETS[size];
|
|
72
|
+
}
|
|
73
|
+
const actualSize = this.resolveSize(size);
|
|
74
|
+
if (actualSize <= 40) return 4;
|
|
75
|
+
if (actualSize <= 60) return 6;
|
|
76
|
+
if (actualSize <= 80) return 8;
|
|
77
|
+
if (actualSize <= 120) return 12;
|
|
78
|
+
return 16;
|
|
79
|
+
}
|
|
80
|
+
applyTheme() {
|
|
81
|
+
const themes = {
|
|
82
|
+
"basic": {
|
|
83
|
+
trackColor: "#e9ecef",
|
|
84
|
+
textColor: null,
|
|
85
|
+
// Use default
|
|
86
|
+
backgroundColor: null
|
|
87
|
+
},
|
|
88
|
+
"shadowed": {
|
|
89
|
+
trackColor: "#d1d5db",
|
|
90
|
+
textColor: null,
|
|
91
|
+
backgroundColor: null,
|
|
92
|
+
shadow: true
|
|
93
|
+
},
|
|
94
|
+
"dark": {
|
|
95
|
+
trackColor: "#374151",
|
|
96
|
+
textColor: "#e5e7eb",
|
|
97
|
+
backgroundColor: "#1f2937"
|
|
98
|
+
},
|
|
99
|
+
"light": {
|
|
100
|
+
trackColor: "#f3f4f6",
|
|
101
|
+
textColor: "#111827",
|
|
102
|
+
backgroundColor: "#ffffff"
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
const themeConfig = themes[this.theme] || themes.basic;
|
|
106
|
+
if (!this.trackColor) {
|
|
107
|
+
this.trackColor = themeConfig.trackColor;
|
|
108
|
+
}
|
|
109
|
+
if (!this.textColor && themeConfig.textColor) {
|
|
110
|
+
this.textColor = themeConfig.textColor;
|
|
111
|
+
}
|
|
112
|
+
if (themeConfig.shadow && this.shadow === false) {
|
|
113
|
+
this.shadow = themeConfig.shadow;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
applyVariant() {
|
|
117
|
+
const variants = {
|
|
118
|
+
"success": { color: "#198754", trackColor: "rgba(25, 135, 84, 0.1)" },
|
|
119
|
+
"danger": { color: "#dc3545", trackColor: "rgba(220, 53, 69, 0.1)" },
|
|
120
|
+
"warning": { color: "#ffc107", trackColor: "rgba(255, 193, 7, 0.1)" },
|
|
121
|
+
"info": { color: "#0dcaf0", trackColor: "rgba(13, 202, 240, 0.1)" },
|
|
122
|
+
"default": { color: "#0d6efd" }
|
|
123
|
+
// Default blue color
|
|
124
|
+
};
|
|
125
|
+
if (variants[this.variant]) {
|
|
126
|
+
const variantColors = variants[this.variant];
|
|
127
|
+
if (!this.color) {
|
|
128
|
+
this.color = variantColors.color;
|
|
129
|
+
}
|
|
130
|
+
if (variantColors.trackColor && this.trackColor === this.applyTheme.trackColor) {
|
|
131
|
+
this.trackColor = variantColors.trackColor;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
if (!this.color) {
|
|
135
|
+
this.color = "#0d6efd";
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
getTemplate() {
|
|
139
|
+
const sizeClass = this.sizePreset ? `circular-progress-${this.sizePreset}` : "";
|
|
140
|
+
const variantClass = this.variant !== "default" ? `circular-progress-${this.variant}` : "";
|
|
141
|
+
const themeClass = this.theme !== "basic" ? `circular-progress-theme-${this.theme}` : "";
|
|
142
|
+
const clickableClass = this.clickable ? "circular-progress-clickable" : "";
|
|
143
|
+
const shadowClass = this.shadow ? "circular-progress-shadow" : "";
|
|
144
|
+
const textColorStyle = this.textColor ? `color: ${this.textColor};` : "";
|
|
145
|
+
return `
|
|
146
|
+
<div class="circular-progress-container ${sizeClass} ${variantClass} ${themeClass} ${clickableClass} ${shadowClass}"
|
|
147
|
+
style="width: ${this.size}px; height: ${this.size}px;">
|
|
148
|
+
<svg class="circular-progress-svg"
|
|
149
|
+
width="${this.size}"
|
|
150
|
+
height="${this.size}"
|
|
151
|
+
viewBox="0 0 ${this.size} ${this.size}">
|
|
152
|
+
</svg>
|
|
153
|
+
<div class="circular-progress-center" style="${textColorStyle}">
|
|
154
|
+
<div class="circular-progress-content"></div>
|
|
155
|
+
</div>
|
|
156
|
+
</div>
|
|
157
|
+
`;
|
|
158
|
+
}
|
|
159
|
+
async onAfterRender() {
|
|
160
|
+
this.svg = this.element.querySelector(".circular-progress-svg");
|
|
161
|
+
this.centerElement = this.element.querySelector(".circular-progress-content");
|
|
162
|
+
this.containerElement = this.element.querySelector(".circular-progress-container");
|
|
163
|
+
this.renderProgress();
|
|
164
|
+
this.renderCenterContent();
|
|
165
|
+
if (this.clickable) {
|
|
166
|
+
this.setupClickHandler();
|
|
167
|
+
}
|
|
168
|
+
if (this.tooltip && this.clickable) {
|
|
169
|
+
this.setupTooltip();
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
renderProgress() {
|
|
173
|
+
if (!this.svg) return;
|
|
174
|
+
this.svg.innerHTML = "";
|
|
175
|
+
const center = this.size / 2;
|
|
176
|
+
const radius = (this.size - this.strokeWidth) / 2;
|
|
177
|
+
const circumference = 2 * Math.PI * radius;
|
|
178
|
+
if (this.gradientColors && this.gradientColors.length > 1) {
|
|
179
|
+
this.createGradient();
|
|
180
|
+
}
|
|
181
|
+
if (this.segments && Array.isArray(this.segments) && this.segments.length > 0) {
|
|
182
|
+
this.renderSegments(center, radius, circumference);
|
|
183
|
+
} else {
|
|
184
|
+
this.renderSingleProgress(center, radius, circumference);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
renderSingleProgress(center, radius, circumference) {
|
|
188
|
+
const arcLength = this.gap > 0 ? 360 - this.gap : 360;
|
|
189
|
+
const arcCircumference = arcLength / 360 * circumference;
|
|
190
|
+
const track = this.createCircle(center, radius, {
|
|
191
|
+
stroke: this.trackColor,
|
|
192
|
+
strokeWidth: this.strokeWidth,
|
|
193
|
+
fill: "none",
|
|
194
|
+
strokeLinecap: this.rounded ? "round" : "butt",
|
|
195
|
+
strokeDasharray: this.gap > 0 ? `${arcCircumference} ${circumference}` : "none",
|
|
196
|
+
transform: `rotate(${this.rotation} ${center} ${center})`
|
|
197
|
+
});
|
|
198
|
+
this.svg.appendChild(track);
|
|
199
|
+
const percentage = this.getPercentage();
|
|
200
|
+
const progressLength = percentage / 100 * arcCircumference;
|
|
201
|
+
const dashOffset = arcCircumference - progressLength;
|
|
202
|
+
const strokeColor = this.gradientColors ? `url(#${this.gradientId})` : this.color;
|
|
203
|
+
const progress = this.createCircle(center, radius, {
|
|
204
|
+
stroke: strokeColor,
|
|
205
|
+
strokeWidth: this.strokeWidth,
|
|
206
|
+
fill: "none",
|
|
207
|
+
strokeLinecap: this.rounded ? "round" : "butt",
|
|
208
|
+
strokeDasharray: `${arcCircumference} ${circumference}`,
|
|
209
|
+
strokeDashoffset: this.animate ? arcCircumference : dashOffset,
|
|
210
|
+
transform: `rotate(${this.rotation} ${center} ${center})`,
|
|
211
|
+
class: "circular-progress-bar"
|
|
212
|
+
});
|
|
213
|
+
this.svg.appendChild(progress);
|
|
214
|
+
if (this.animate) {
|
|
215
|
+
this.animateProgress(progress, dashOffset);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
renderSegments(center, radius, circumference) {
|
|
219
|
+
const arcLength = this.gap > 0 ? 360 - this.gap : 360;
|
|
220
|
+
const arcCircumference = arcLength / 360 * circumference;
|
|
221
|
+
const track = this.createCircle(center, radius, {
|
|
222
|
+
stroke: this.trackColor,
|
|
223
|
+
strokeWidth: this.strokeWidth,
|
|
224
|
+
fill: "none",
|
|
225
|
+
strokeLinecap: this.rounded ? "round" : "butt",
|
|
226
|
+
strokeDasharray: this.gap > 0 ? `${arcCircumference} ${circumference}` : "none",
|
|
227
|
+
transform: `rotate(${this.rotation} ${center} ${center})`
|
|
228
|
+
});
|
|
229
|
+
this.svg.appendChild(track);
|
|
230
|
+
const total = this.segments.reduce((sum, seg) => sum + (seg.value || 0), 0);
|
|
231
|
+
if (total > this.max) {
|
|
232
|
+
console.warn("CircularProgress: Segment total exceeds max value. Clamping to max.");
|
|
233
|
+
}
|
|
234
|
+
let currentOffset = 0;
|
|
235
|
+
this.segments.forEach((segment, index) => {
|
|
236
|
+
const segmentPercentage = (segment.value || 0) / (this.max - this.min) * 100;
|
|
237
|
+
const segmentLength = segmentPercentage / 100 * arcCircumference;
|
|
238
|
+
const gapLength = this.segmentGap / 360 * circumference;
|
|
239
|
+
if (segmentLength > 0) {
|
|
240
|
+
const segmentCircle = this.createCircle(center, radius, {
|
|
241
|
+
stroke: segment.color || this.color,
|
|
242
|
+
strokeWidth: this.strokeWidth,
|
|
243
|
+
fill: "none",
|
|
244
|
+
strokeLinecap: this.rounded ? "round" : "butt",
|
|
245
|
+
strokeDasharray: `${segmentLength} ${circumference}`,
|
|
246
|
+
strokeDashoffset: this.animate ? arcCircumference : -currentOffset,
|
|
247
|
+
transform: `rotate(${this.rotation} ${center} ${center})`,
|
|
248
|
+
class: `circular-progress-segment circular-progress-segment-${index}`,
|
|
249
|
+
"data-segment-index": index
|
|
250
|
+
});
|
|
251
|
+
this.svg.appendChild(segmentCircle);
|
|
252
|
+
if (this.animate) {
|
|
253
|
+
this.animateProgress(segmentCircle, -currentOffset, index * 100);
|
|
254
|
+
}
|
|
255
|
+
currentOffset += segmentLength + gapLength;
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
createCircle(cx, cy, attributes = {}) {
|
|
260
|
+
const circle = document.createElementNS("http://www.w3.org/2000/svg", "circle");
|
|
261
|
+
circle.setAttribute("cx", cx);
|
|
262
|
+
circle.setAttribute("cy", cx);
|
|
263
|
+
circle.setAttribute("r", cy);
|
|
264
|
+
Object.entries(attributes).forEach(([key, value]) => {
|
|
265
|
+
if (key === "strokeWidth") {
|
|
266
|
+
circle.setAttribute("stroke-width", value);
|
|
267
|
+
} else if (key === "strokeLinecap") {
|
|
268
|
+
circle.setAttribute("stroke-linecap", value);
|
|
269
|
+
} else if (key === "strokeDasharray") {
|
|
270
|
+
circle.setAttribute("stroke-dasharray", value);
|
|
271
|
+
} else if (key === "strokeDashoffset") {
|
|
272
|
+
circle.setAttribute("stroke-dashoffset", value);
|
|
273
|
+
} else {
|
|
274
|
+
circle.setAttribute(key, value);
|
|
275
|
+
}
|
|
276
|
+
});
|
|
277
|
+
return circle;
|
|
278
|
+
}
|
|
279
|
+
createGradient() {
|
|
280
|
+
const defs = document.createElementNS("http://www.w3.org/2000/svg", "defs");
|
|
281
|
+
const gradient = document.createElementNS("http://www.w3.org/2000/svg", "linearGradient");
|
|
282
|
+
gradient.setAttribute("id", this.gradientId);
|
|
283
|
+
gradient.setAttribute("x1", "0%");
|
|
284
|
+
gradient.setAttribute("y1", "0%");
|
|
285
|
+
gradient.setAttribute("x2", "100%");
|
|
286
|
+
gradient.setAttribute("y2", "100%");
|
|
287
|
+
this.gradientColors.forEach((color, index) => {
|
|
288
|
+
const stop = document.createElementNS("http://www.w3.org/2000/svg", "stop");
|
|
289
|
+
const offset = index / (this.gradientColors.length - 1) * 100;
|
|
290
|
+
stop.setAttribute("offset", `${offset}%`);
|
|
291
|
+
stop.setAttribute("stop-color", color);
|
|
292
|
+
gradient.appendChild(stop);
|
|
293
|
+
});
|
|
294
|
+
defs.appendChild(gradient);
|
|
295
|
+
this.svg.appendChild(defs);
|
|
296
|
+
}
|
|
297
|
+
animateProgress(circle, targetOffset, delay = 0) {
|
|
298
|
+
setTimeout(() => {
|
|
299
|
+
circle.style.transition = `stroke-dashoffset ${this.animationDuration}ms ${this.animationEasing}`;
|
|
300
|
+
circle.style.strokeDashoffset = targetOffset;
|
|
301
|
+
}, delay);
|
|
302
|
+
}
|
|
303
|
+
renderCenterContent() {
|
|
304
|
+
if (!this.centerElement) return;
|
|
305
|
+
if (this.labelHtml) {
|
|
306
|
+
this.centerElement.innerHTML = this.labelHtml;
|
|
307
|
+
} else if (this.icon) {
|
|
308
|
+
this.centerElement.innerHTML = `<i class="${this.icon}"></i>`;
|
|
309
|
+
} else if (this.showValue) {
|
|
310
|
+
const formattedValue = this.getFormattedValue();
|
|
311
|
+
let html = `<div class="circular-progress-value">${formattedValue}</div>`;
|
|
312
|
+
if (this.label) {
|
|
313
|
+
html += `<div class="circular-progress-label">${this.label}</div>`;
|
|
314
|
+
}
|
|
315
|
+
this.centerElement.innerHTML = html;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
getFormattedValue() {
|
|
319
|
+
const value = this.value;
|
|
320
|
+
const min = this.min;
|
|
321
|
+
const max = this.max;
|
|
322
|
+
if (this.valueFormatter && typeof this.valueFormatter === "function") {
|
|
323
|
+
return this.valueFormatter(value, min, max);
|
|
324
|
+
}
|
|
325
|
+
switch (this.valueFormat) {
|
|
326
|
+
case "percentage":
|
|
327
|
+
return `${Math.round(this.getPercentage())}%`;
|
|
328
|
+
case "fraction":
|
|
329
|
+
return `${value}/${max}`;
|
|
330
|
+
case "value":
|
|
331
|
+
return value.toString();
|
|
332
|
+
default:
|
|
333
|
+
if (this.dataFormatter) {
|
|
334
|
+
try {
|
|
335
|
+
return this.dataFormatter.pipe(value, this.valueFormat);
|
|
336
|
+
} catch (error) {
|
|
337
|
+
console.warn("CircularProgress: DataFormatter error, falling back to percentage", error);
|
|
338
|
+
return `${Math.round(this.getPercentage())}%`;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
return `${Math.round(this.getPercentage())}%`;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
getPercentage() {
|
|
345
|
+
const range = this.max - this.min;
|
|
346
|
+
if (range === 0) return 0;
|
|
347
|
+
return (this.value - this.min) / range * 100;
|
|
348
|
+
}
|
|
349
|
+
setupClickHandler() {
|
|
350
|
+
if (!this.containerElement) return;
|
|
351
|
+
this.containerElement.style.cursor = "pointer";
|
|
352
|
+
this.containerElement.addEventListener("click", (e) => {
|
|
353
|
+
e.preventDefault();
|
|
354
|
+
e.stopPropagation();
|
|
355
|
+
const percentage = this.getPercentage();
|
|
356
|
+
this.emit("progress:clicked", {
|
|
357
|
+
value: this.value,
|
|
358
|
+
percentage,
|
|
359
|
+
min: this.min,
|
|
360
|
+
max: this.max
|
|
361
|
+
});
|
|
362
|
+
if (this.tooltip) {
|
|
363
|
+
this.togglePopover();
|
|
364
|
+
}
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
setupTooltip() {
|
|
368
|
+
}
|
|
369
|
+
togglePopover() {
|
|
370
|
+
if (!this.containerElement || typeof window.bootstrap === "undefined") {
|
|
371
|
+
console.warn("CircularProgress: Bootstrap is required for tooltip support");
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
374
|
+
if (!this.popover) {
|
|
375
|
+
const content = this.getTooltipContent();
|
|
376
|
+
const title = typeof this.tooltip === "object" && this.tooltip.title ? this.tooltip.title : void 0;
|
|
377
|
+
const popoverConfig = {
|
|
378
|
+
content,
|
|
379
|
+
html: true,
|
|
380
|
+
placement: this.tooltipPlacement,
|
|
381
|
+
trigger: "manual",
|
|
382
|
+
container: "body"
|
|
383
|
+
};
|
|
384
|
+
if (title) {
|
|
385
|
+
popoverConfig.title = title;
|
|
386
|
+
}
|
|
387
|
+
this.popover = new window.bootstrap.Popover(this.containerElement, popoverConfig);
|
|
388
|
+
}
|
|
389
|
+
const popoverElement = window.bootstrap.Popover.getInstance(this.containerElement);
|
|
390
|
+
if (popoverElement && this.containerElement.getAttribute("aria-describedby")) {
|
|
391
|
+
this.popover.hide();
|
|
392
|
+
} else {
|
|
393
|
+
this.popover.setContent({
|
|
394
|
+
".popover-body": this.getTooltipContent()
|
|
395
|
+
});
|
|
396
|
+
this.popover.show();
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
getTooltipContent() {
|
|
400
|
+
if (typeof this.tooltip === "function") {
|
|
401
|
+
return this.tooltip(this.value, {
|
|
402
|
+
min: this.min,
|
|
403
|
+
max: this.max,
|
|
404
|
+
percentage: this.getPercentage()
|
|
405
|
+
});
|
|
406
|
+
}
|
|
407
|
+
if (typeof this.tooltip === "object") {
|
|
408
|
+
return this.tooltip.html || this.tooltip.content || "";
|
|
409
|
+
}
|
|
410
|
+
return this.tooltip || "";
|
|
411
|
+
}
|
|
412
|
+
// Public API
|
|
413
|
+
setValue(value, animate = true) {
|
|
414
|
+
this.value;
|
|
415
|
+
this.value = Math.max(this.min, Math.min(this.max, value));
|
|
416
|
+
this.renderCenterContent();
|
|
417
|
+
if (this.svg && !this.segments) {
|
|
418
|
+
const progressBar = this.svg.querySelector(".circular-progress-bar");
|
|
419
|
+
if (progressBar) {
|
|
420
|
+
const radius = this.size / 2 - this.strokeWidth / 2;
|
|
421
|
+
const circumference = 2 * Math.PI * radius;
|
|
422
|
+
const arcLength = this.gap > 0 ? 360 - this.gap : 360;
|
|
423
|
+
const arcCircumference = arcLength / 360 * circumference;
|
|
424
|
+
const percentage = this.getPercentage();
|
|
425
|
+
const progressLength = percentage / 100 * arcCircumference;
|
|
426
|
+
const dashOffset = arcCircumference - progressLength;
|
|
427
|
+
if (animate) {
|
|
428
|
+
progressBar.style.transition = `stroke-dashoffset ${this.animationDuration}ms ${this.animationEasing}`;
|
|
429
|
+
progressBar.style.strokeDashoffset = dashOffset;
|
|
430
|
+
} else {
|
|
431
|
+
progressBar.style.transition = "none";
|
|
432
|
+
progressBar.style.strokeDashoffset = dashOffset;
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
} else {
|
|
436
|
+
const oldAnimate = this.animate;
|
|
437
|
+
this.animate = animate;
|
|
438
|
+
this.renderProgress();
|
|
439
|
+
this.animate = oldAnimate;
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
setRange(min, max) {
|
|
443
|
+
this.min = min;
|
|
444
|
+
this.max = max;
|
|
445
|
+
this.renderProgress();
|
|
446
|
+
this.renderCenterContent();
|
|
447
|
+
}
|
|
448
|
+
increment(amount = 1) {
|
|
449
|
+
this.setValue(this.value + amount);
|
|
450
|
+
}
|
|
451
|
+
decrement(amount = 1) {
|
|
452
|
+
this.setValue(this.value - amount);
|
|
453
|
+
}
|
|
454
|
+
setColor(color) {
|
|
455
|
+
this.color = color;
|
|
456
|
+
this.gradientColors = null;
|
|
457
|
+
if (this.svg && !this.segments) {
|
|
458
|
+
const progressBar = this.svg.querySelector(".circular-progress-bar");
|
|
459
|
+
if (progressBar) {
|
|
460
|
+
progressBar.setAttribute("stroke", color);
|
|
461
|
+
}
|
|
462
|
+
} else {
|
|
463
|
+
this.renderProgress();
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
setGradient(colors) {
|
|
467
|
+
if (Array.isArray(colors) && colors.length > 1) {
|
|
468
|
+
this.gradientColors = colors;
|
|
469
|
+
this.gradientId = `gradient-${Math.random().toString(36).substr(2, 9)}`;
|
|
470
|
+
this.renderProgress();
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
setSize(size) {
|
|
474
|
+
if (this.containerElement && this.sizePreset) {
|
|
475
|
+
this.containerElement.classList.remove(`circular-progress-${this.sizePreset}`);
|
|
476
|
+
}
|
|
477
|
+
this.sizePreset = typeof size === "string" && this.SIZE_PRESETS[size] ? size : null;
|
|
478
|
+
this.size = this.resolveSize(size);
|
|
479
|
+
this.strokeWidth = this.getAutoStrokeWidth(size);
|
|
480
|
+
if (this.containerElement) {
|
|
481
|
+
this.containerElement.style.width = `${this.size}px`;
|
|
482
|
+
this.containerElement.style.height = `${this.size}px`;
|
|
483
|
+
if (this.sizePreset) {
|
|
484
|
+
this.containerElement.classList.add(`circular-progress-${this.sizePreset}`);
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
if (this.svg) {
|
|
488
|
+
this.svg.setAttribute("width", this.size);
|
|
489
|
+
this.svg.setAttribute("height", this.size);
|
|
490
|
+
this.svg.setAttribute("viewBox", `0 0 ${this.size} ${this.size}`);
|
|
491
|
+
}
|
|
492
|
+
this.renderProgress();
|
|
493
|
+
}
|
|
494
|
+
animateTo(targetValue, duration = 1e3) {
|
|
495
|
+
const startValue = this.value;
|
|
496
|
+
const diff = targetValue - startValue;
|
|
497
|
+
const startTime = performance.now();
|
|
498
|
+
const animate = (currentTime) => {
|
|
499
|
+
const elapsed = currentTime - startTime;
|
|
500
|
+
const progress = Math.min(elapsed / duration, 1);
|
|
501
|
+
const easeProgress = 1 - Math.pow(1 - progress, 3);
|
|
502
|
+
const newValue = startValue + diff * easeProgress;
|
|
503
|
+
this.setValue(newValue, false);
|
|
504
|
+
if (progress < 1) {
|
|
505
|
+
requestAnimationFrame(animate);
|
|
506
|
+
} else {
|
|
507
|
+
this.setValue(targetValue, false);
|
|
508
|
+
}
|
|
509
|
+
};
|
|
510
|
+
requestAnimationFrame(animate);
|
|
511
|
+
}
|
|
512
|
+
pulse() {
|
|
513
|
+
if (!this.containerElement) return;
|
|
514
|
+
this.containerElement.style.animation = "none";
|
|
515
|
+
setTimeout(() => {
|
|
516
|
+
this.containerElement.style.animation = "circular-progress-pulse 0.5s ease-out";
|
|
517
|
+
}, 10);
|
|
518
|
+
setTimeout(() => {
|
|
519
|
+
this.containerElement.style.animation = "";
|
|
520
|
+
}, 500);
|
|
521
|
+
}
|
|
522
|
+
complete() {
|
|
523
|
+
this.variant = "success";
|
|
524
|
+
this.applyVariant();
|
|
525
|
+
this.setValue(this.max);
|
|
526
|
+
this.pulse();
|
|
527
|
+
}
|
|
528
|
+
reset() {
|
|
529
|
+
this.setValue(this.min);
|
|
530
|
+
}
|
|
531
|
+
hide() {
|
|
532
|
+
if (this.element) {
|
|
533
|
+
this.element.style.display = "none";
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
show() {
|
|
537
|
+
if (this.element) {
|
|
538
|
+
this.element.style.display = "";
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
getValue() {
|
|
542
|
+
return this.value;
|
|
543
|
+
}
|
|
544
|
+
getPercentageValue() {
|
|
545
|
+
return this.getPercentage();
|
|
546
|
+
}
|
|
547
|
+
async onBeforeDestroy() {
|
|
548
|
+
if (this.popover) {
|
|
549
|
+
this.popover.dispose();
|
|
550
|
+
this.popover = null;
|
|
551
|
+
}
|
|
552
|
+
await super.onBeforeDestroy();
|
|
553
|
+
}
|
|
554
|
+
}
|
|
4
555
|
export {
|
|
5
556
|
B2 as BUILD_TIME,
|
|
6
557
|
B as BaseChart,
|
|
558
|
+
CircularProgress,
|
|
7
559
|
M as MetricsChart,
|
|
8
560
|
b as MetricsMiniChart,
|
|
9
561
|
c as MetricsMiniChartWidget,
|
package/dist/charts.es.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"charts.es.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;"}
|
|
1
|
+
{"version":3,"file":"charts.es.js","sources":["../src/extensions/charts/CircularProgress.js"],"sourcesContent":["/**\n * CircularProgress - Modern circular progress indicator component\n * Supports single/multi-segment progress, animations, gradients, and tooltips\n * Uses SVG for crisp rendering at any size\n */\n\nimport View from '@core/View.js';\nimport dataFormatter from '@core/utils/DataFormatter.js';\n\nexport default class CircularProgress extends View {\n constructor(options = {}) {\n super({\n className: `circular-progress ${options.className || ''}`,\n ...options\n });\n\n // Size presets\n this.SIZE_PRESETS = {\n 'xs': 40,\n 'sm': 60,\n 'md': 80,\n 'lg': 120,\n 'xl': 180\n };\n\n // Stroke width presets (auto-calculated based on size)\n this.STROKE_PRESETS = {\n 'xs': 4,\n 'sm': 6,\n 'md': 8,\n 'lg': 12,\n 'xl': 16\n };\n\n // Core configuration\n this.value = options.value !== undefined ? options.value : 0;\n this.min = options.min !== undefined ? options.min : 0;\n this.max = options.max !== undefined ? options.max : 100;\n\n // Dimensions\n this.sizePreset = (typeof options.size === 'string' && this.SIZE_PRESETS[options.size]) ? options.size : null;\n this.size = this.resolveSize(options.size !== undefined ? options.size : 'md');\n this.strokeWidth = options.strokeWidth === 'auto' || options.strokeWidth === undefined\n ? this.getAutoStrokeWidth(options.size)\n : options.strokeWidth;\n\n // Colors & Styling\n this.theme = options.theme || 'basic'; // 'basic', '3d', 'dark', 'light'\n this.variant = options.variant || 'default';\n this.color = options.color; // Will be set by applyVariant if not provided\n this.trackColor = options.trackColor; // Will be set by applyTheme if not provided\n this.textColor = options.textColor; // Custom text color\n this.gradientColors = options.gradientColors || null;\n\n // Apply theme (sets colors based on theme)\n this.applyTheme();\n \n // Apply variant colors (sets this.color if not provided)\n this.applyVariant();\n\n // Arc configuration\n this.rotation = options.rotation !== undefined ? options.rotation : -90; // Start at top\n this.gap = options.gap || 0; // Gap in degrees (0 = full circle)\n\n // Center content\n this.showValue = options.showValue !== false;\n this.valueFormat = options.valueFormat || 'percentage';\n this.valueFormatter = options.valueFormatter || null;\n this.label = options.label || null;\n this.labelHtml = options.labelHtml || null;\n this.icon = options.icon || null;\n\n // Animation\n this.animate = options.animate !== false;\n this.animationDuration = options.animationDuration || 600;\n this.animationEasing = options.animationEasing || 'ease-out';\n\n // Visual options\n this.rounded = options.rounded !== false;\n this.shadow = options.shadow || false;\n\n // Interaction\n this.clickable = options.clickable || false;\n this.tooltip = options.tooltip || null;\n this.tooltipPlacement = options.tooltipPlacement || 'top';\n\n // Multi-segment mode\n this.segments = options.segments || null;\n this.segmentGap = options.segmentGap || 2; // Gap between segments in degrees\n\n // DataFormatter instance\n this.dataFormatter = dataFormatter;\n\n // Internal state\n this.svg = null;\n this.centerElement = null;\n this.popover = null;\n this.gradientId = `gradient-${Math.random().toString(36).substr(2, 9)}`;\n }\n\n resolveSize(size) {\n if (typeof size === 'string' && this.SIZE_PRESETS[size]) {\n return this.SIZE_PRESETS[size];\n }\n return typeof size === 'number' ? size : this.SIZE_PRESETS.md;\n }\n\n getAutoStrokeWidth(size) {\n if (typeof size === 'string' && this.STROKE_PRESETS[size]) {\n return this.STROKE_PRESETS[size];\n }\n // Auto-calculate based on size\n const actualSize = this.resolveSize(size);\n if (actualSize <= 40) return 4;\n if (actualSize <= 60) return 6;\n if (actualSize <= 80) return 8;\n if (actualSize <= 120) return 12;\n return 16;\n }\n\n applyTheme() {\n const themes = {\n 'basic': {\n trackColor: '#e9ecef',\n textColor: null, // Use default\n backgroundColor: null\n },\n 'shadowed': {\n trackColor: '#d1d5db',\n textColor: null,\n backgroundColor: null,\n shadow: true\n },\n 'dark': {\n trackColor: '#374151',\n textColor: '#e5e7eb',\n backgroundColor: '#1f2937'\n },\n 'light': {\n trackColor: '#f3f4f6',\n textColor: '#111827',\n backgroundColor: '#ffffff'\n }\n };\n\n const themeConfig = themes[this.theme] || themes.basic;\n \n // Apply theme defaults if not explicitly set\n if (!this.trackColor) {\n this.trackColor = themeConfig.trackColor;\n }\n if (!this.textColor && themeConfig.textColor) {\n this.textColor = themeConfig.textColor;\n }\n if (themeConfig.shadow && this.shadow === false) {\n this.shadow = themeConfig.shadow;\n }\n }\n\n applyVariant() {\n const variants = {\n 'success': { color: '#198754', trackColor: 'rgba(25, 135, 84, 0.1)' },\n 'danger': { color: '#dc3545', trackColor: 'rgba(220, 53, 69, 0.1)' },\n 'warning': { color: '#ffc107', trackColor: 'rgba(255, 193, 7, 0.1)' },\n 'info': { color: '#0dcaf0', trackColor: 'rgba(13, 202, 240, 0.1)' },\n 'default': { color: '#0d6efd' } // Default blue color\n };\n\n if (variants[this.variant]) {\n const variantColors = variants[this.variant];\n if (!this.color) {\n this.color = variantColors.color;\n }\n if (variantColors.trackColor && this.trackColor === this.applyTheme.trackColor) {\n this.trackColor = variantColors.trackColor;\n }\n }\n \n // Fallback if no color is set\n if (!this.color) {\n this.color = '#0d6efd';\n }\n }\n\n getTemplate() {\n const sizeClass = this.sizePreset ? `circular-progress-${this.sizePreset}` : '';\n const variantClass = this.variant !== 'default' ? `circular-progress-${this.variant}` : '';\n const themeClass = this.theme !== 'basic' ? `circular-progress-theme-${this.theme}` : '';\n const clickableClass = this.clickable ? 'circular-progress-clickable' : '';\n const shadowClass = this.shadow ? 'circular-progress-shadow' : '';\n \n const textColorStyle = this.textColor ? `color: ${this.textColor};` : '';\n\n return `\n <div class=\"circular-progress-container ${sizeClass} ${variantClass} ${themeClass} ${clickableClass} ${shadowClass}\"\n style=\"width: ${this.size}px; height: ${this.size}px;\">\n <svg class=\"circular-progress-svg\" \n width=\"${this.size}\" \n height=\"${this.size}\"\n viewBox=\"0 0 ${this.size} ${this.size}\">\n </svg>\n <div class=\"circular-progress-center\" style=\"${textColorStyle}\">\n <div class=\"circular-progress-content\"></div>\n </div>\n </div>\n `;\n }\n\n async onAfterRender() {\n this.svg = this.element.querySelector('.circular-progress-svg');\n this.centerElement = this.element.querySelector('.circular-progress-content');\n this.containerElement = this.element.querySelector('.circular-progress-container');\n\n // Render the progress circle\n this.renderProgress();\n\n // Render center content\n this.renderCenterContent();\n\n // Setup interactions\n if (this.clickable) {\n this.setupClickHandler();\n }\n\n // Setup tooltip\n if (this.tooltip && this.clickable) {\n this.setupTooltip();\n }\n }\n\n renderProgress() {\n if (!this.svg) return;\n\n // Clear previous content\n this.svg.innerHTML = '';\n\n const center = this.size / 2;\n const radius = (this.size - this.strokeWidth) / 2;\n const circumference = 2 * Math.PI * radius;\n\n // Create gradient definition if needed\n if (this.gradientColors && this.gradientColors.length > 1) {\n this.createGradient();\n }\n\n // Determine if we're using segments or single progress\n if (this.segments && Array.isArray(this.segments) && this.segments.length > 0) {\n this.renderSegments(center, radius, circumference);\n } else {\n this.renderSingleProgress(center, radius, circumference);\n }\n }\n\n renderSingleProgress(center, radius, circumference) {\n // Calculate arc length\n const arcLength = this.gap > 0 ? (360 - this.gap) : 360;\n const arcCircumference = (arcLength / 360) * circumference;\n\n // Create track (background circle/arc)\n const track = this.createCircle(center, radius, {\n stroke: this.trackColor,\n strokeWidth: this.strokeWidth,\n fill: 'none',\n strokeLinecap: this.rounded ? 'round' : 'butt',\n strokeDasharray: this.gap > 0 ? `${arcCircumference} ${circumference}` : 'none',\n transform: `rotate(${this.rotation} ${center} ${center})`\n });\n this.svg.appendChild(track);\n\n // Create progress circle\n const percentage = this.getPercentage();\n const progressLength = (percentage / 100) * arcCircumference;\n const dashOffset = arcCircumference - progressLength;\n\n const strokeColor = this.gradientColors ? `url(#${this.gradientId})` : this.color;\n\n const progress = this.createCircle(center, radius, {\n stroke: strokeColor,\n strokeWidth: this.strokeWidth,\n fill: 'none',\n strokeLinecap: this.rounded ? 'round' : 'butt',\n strokeDasharray: `${arcCircumference} ${circumference}`,\n strokeDashoffset: this.animate ? arcCircumference : dashOffset,\n transform: `rotate(${this.rotation} ${center} ${center})`,\n class: 'circular-progress-bar'\n });\n\n this.svg.appendChild(progress);\n\n // Apply animation\n if (this.animate) {\n this.animateProgress(progress, dashOffset);\n }\n }\n\n renderSegments(center, radius, circumference) {\n // Calculate arc length\n const arcLength = this.gap > 0 ? (360 - this.gap) : 360;\n const arcCircumference = (arcLength / 360) * circumference;\n\n // Create track\n const track = this.createCircle(center, radius, {\n stroke: this.trackColor,\n strokeWidth: this.strokeWidth,\n fill: 'none',\n strokeLinecap: this.rounded ? 'round' : 'butt',\n strokeDasharray: this.gap > 0 ? `${arcCircumference} ${circumference}` : 'none',\n transform: `rotate(${this.rotation} ${center} ${center})`\n });\n this.svg.appendChild(track);\n\n // Validate segments total\n const total = this.segments.reduce((sum, seg) => sum + (seg.value || 0), 0);\n if (total > this.max) {\n console.warn('CircularProgress: Segment total exceeds max value. Clamping to max.');\n }\n\n // Render each segment\n let currentOffset = 0;\n\n this.segments.forEach((segment, index) => {\n const segmentPercentage = ((segment.value || 0) / (this.max - this.min)) * 100;\n const segmentLength = (segmentPercentage / 100) * arcCircumference;\n\n // Gap between segments (in circumference units)\n const gapLength = (this.segmentGap / 360) * circumference;\n\n if (segmentLength > 0) {\n const segmentCircle = this.createCircle(center, radius, {\n stroke: segment.color || this.color,\n strokeWidth: this.strokeWidth,\n fill: 'none',\n strokeLinecap: this.rounded ? 'round' : 'butt',\n strokeDasharray: `${segmentLength} ${circumference}`,\n strokeDashoffset: this.animate ? arcCircumference : -(currentOffset),\n transform: `rotate(${this.rotation} ${center} ${center})`,\n class: `circular-progress-segment circular-progress-segment-${index}`,\n 'data-segment-index': index\n });\n\n this.svg.appendChild(segmentCircle);\n\n // Apply animation\n if (this.animate) {\n this.animateProgress(segmentCircle, -(currentOffset), index * 100);\n }\n\n // Update offset for next segment\n currentOffset += segmentLength + gapLength;\n }\n });\n }\n\n createCircle(cx, cy, attributes = {}) {\n const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');\n circle.setAttribute('cx', cx);\n circle.setAttribute('cy', cx); // Use cx for cy since we pass center for both\n circle.setAttribute('r', cy); // cy parameter is actually the radius\n\n Object.entries(attributes).forEach(([key, value]) => {\n if (key === 'strokeWidth') {\n circle.setAttribute('stroke-width', value);\n } else if (key === 'strokeLinecap') {\n circle.setAttribute('stroke-linecap', value);\n } else if (key === 'strokeDasharray') {\n circle.setAttribute('stroke-dasharray', value);\n } else if (key === 'strokeDashoffset') {\n circle.setAttribute('stroke-dashoffset', value);\n } else {\n circle.setAttribute(key, value);\n }\n });\n\n return circle;\n }\n\n createGradient() {\n const defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');\n const gradient = document.createElementNS('http://www.w3.org/2000/svg', 'linearGradient');\n gradient.setAttribute('id', this.gradientId);\n gradient.setAttribute('x1', '0%');\n gradient.setAttribute('y1', '0%');\n gradient.setAttribute('x2', '100%');\n gradient.setAttribute('y2', '100%');\n\n this.gradientColors.forEach((color, index) => {\n const stop = document.createElementNS('http://www.w3.org/2000/svg', 'stop');\n const offset = (index / (this.gradientColors.length - 1)) * 100;\n stop.setAttribute('offset', `${offset}%`);\n stop.setAttribute('stop-color', color);\n gradient.appendChild(stop);\n });\n\n defs.appendChild(gradient);\n this.svg.appendChild(defs);\n }\n\n animateProgress(circle, targetOffset, delay = 0) {\n setTimeout(() => {\n circle.style.transition = `stroke-dashoffset ${this.animationDuration}ms ${this.animationEasing}`;\n circle.style.strokeDashoffset = targetOffset;\n }, delay);\n }\n\n renderCenterContent() {\n if (!this.centerElement) return;\n\n // Priority: labelHtml > icon > value/label\n if (this.labelHtml) {\n this.centerElement.innerHTML = this.labelHtml;\n } else if (this.icon) {\n this.centerElement.innerHTML = `<i class=\"${this.icon}\"></i>`;\n } else if (this.showValue) {\n const formattedValue = this.getFormattedValue();\n let html = `<div class=\"circular-progress-value\">${formattedValue}</div>`;\n \n if (this.label) {\n html += `<div class=\"circular-progress-label\">${this.label}</div>`;\n }\n\n this.centerElement.innerHTML = html;\n }\n }\n\n getFormattedValue() {\n const value = this.value;\n const min = this.min;\n const max = this.max;\n\n // Custom formatter function takes precedence\n if (this.valueFormatter && typeof this.valueFormatter === 'function') {\n return this.valueFormatter(value, min, max);\n }\n\n // Built-in formats\n switch (this.valueFormat) {\n case 'percentage':\n return `${Math.round(this.getPercentage())}%`;\n \n case 'fraction':\n return `${value}/${max}`;\n \n case 'value':\n return value.toString();\n \n default:\n // Try DataFormatter\n if (this.dataFormatter) {\n try {\n return this.dataFormatter.pipe(value, this.valueFormat);\n } catch (error) {\n console.warn('CircularProgress: DataFormatter error, falling back to percentage', error);\n return `${Math.round(this.getPercentage())}%`;\n }\n }\n return `${Math.round(this.getPercentage())}%`;\n }\n }\n\n getPercentage() {\n const range = this.max - this.min;\n if (range === 0) return 0;\n return ((this.value - this.min) / range) * 100;\n }\n\n setupClickHandler() {\n if (!this.containerElement) return;\n\n this.containerElement.style.cursor = 'pointer';\n \n this.containerElement.addEventListener('click', (e) => {\n e.preventDefault();\n e.stopPropagation();\n\n const percentage = this.getPercentage();\n \n this.emit('progress:clicked', {\n value: this.value,\n percentage,\n min: this.min,\n max: this.max\n });\n\n // Toggle popover if tooltip is configured\n if (this.tooltip) {\n this.togglePopover();\n }\n });\n }\n\n setupTooltip() {\n // Bootstrap popover will be initialized on first click\n // We'll create the popover content dynamically\n }\n\n togglePopover() {\n if (!this.containerElement || typeof window.bootstrap === 'undefined') {\n console.warn('CircularProgress: Bootstrap is required for tooltip support');\n return;\n }\n\n // Get or create popover instance\n if (!this.popover) {\n const content = this.getTooltipContent();\n const title = typeof this.tooltip === 'object' && this.tooltip.title ? this.tooltip.title : undefined;\n\n // Build config object, omitting title if undefined\n const popoverConfig = {\n content: content,\n html: true,\n placement: this.tooltipPlacement,\n trigger: 'manual',\n container: 'body'\n };\n \n // Only add title if it exists\n if (title) {\n popoverConfig.title = title;\n }\n\n this.popover = new window.bootstrap.Popover(this.containerElement, popoverConfig);\n }\n\n // Toggle visibility\n const popoverElement = window.bootstrap.Popover.getInstance(this.containerElement);\n if (popoverElement && this.containerElement.getAttribute('aria-describedby')) {\n this.popover.hide();\n } else {\n // Update content before showing\n this.popover.setContent({\n '.popover-body': this.getTooltipContent()\n });\n this.popover.show();\n }\n }\n\n getTooltipContent() {\n if (typeof this.tooltip === 'function') {\n return this.tooltip(this.value, {\n min: this.min,\n max: this.max,\n percentage: this.getPercentage()\n });\n }\n\n if (typeof this.tooltip === 'object') {\n return this.tooltip.html || this.tooltip.content || '';\n }\n\n return this.tooltip || '';\n }\n\n // Public API\n\n setValue(value, animate = true) {\n const oldValue = this.value;\n this.value = Math.max(this.min, Math.min(this.max, value));\n \n // Update center content\n this.renderCenterContent();\n \n // Update progress without full re-render\n if (this.svg && !this.segments) {\n const progressBar = this.svg.querySelector('.circular-progress-bar');\n if (progressBar) {\n const radius = (this.size / 2) - (this.strokeWidth / 2);\n const circumference = 2 * Math.PI * radius;\n const arcLength = this.gap > 0 ? (360 - this.gap) : 360;\n const arcCircumference = (arcLength / 360) * circumference;\n const percentage = this.getPercentage();\n const progressLength = (percentage / 100) * arcCircumference;\n const dashOffset = arcCircumference - progressLength;\n \n if (animate) {\n // Animate from current offset to new offset\n progressBar.style.transition = `stroke-dashoffset ${this.animationDuration}ms ${this.animationEasing}`;\n progressBar.style.strokeDashoffset = dashOffset;\n } else {\n // Update immediately without animation\n progressBar.style.transition = 'none';\n progressBar.style.strokeDashoffset = dashOffset;\n }\n }\n } else {\n // For segments or if no existing progress bar, do full re-render\n const oldAnimate = this.animate;\n this.animate = animate;\n this.renderProgress();\n this.animate = oldAnimate;\n }\n }\n\n setRange(min, max) {\n this.min = min;\n this.max = max;\n this.renderProgress();\n this.renderCenterContent();\n }\n\n increment(amount = 1) {\n this.setValue(this.value + amount);\n }\n\n decrement(amount = 1) {\n this.setValue(this.value - amount);\n }\n\n setColor(color) {\n this.color = color;\n this.gradientColors = null; // Clear gradient\n \n // Update color without full re-render\n if (this.svg && !this.segments) {\n const progressBar = this.svg.querySelector('.circular-progress-bar');\n if (progressBar) {\n progressBar.setAttribute('stroke', color);\n }\n } else {\n // For segments, need to re-render\n this.renderProgress();\n }\n }\n\n setGradient(colors) {\n if (Array.isArray(colors) && colors.length > 1) {\n this.gradientColors = colors;\n this.gradientId = `gradient-${Math.random().toString(36).substr(2, 9)}`;\n this.renderProgress();\n }\n }\n\n setSize(size) {\n // Remove old size class if it exists\n if (this.containerElement && this.sizePreset) {\n this.containerElement.classList.remove(`circular-progress-${this.sizePreset}`);\n }\n \n // Update size preset if the new size is a preset string\n this.sizePreset = (typeof size === 'string' && this.SIZE_PRESETS[size]) ? size : null;\n this.size = this.resolveSize(size);\n this.strokeWidth = this.getAutoStrokeWidth(size);\n \n // Add new size class if it's a preset\n if (this.containerElement) {\n this.containerElement.style.width = `${this.size}px`;\n this.containerElement.style.height = `${this.size}px`;\n \n if (this.sizePreset) {\n this.containerElement.classList.add(`circular-progress-${this.sizePreset}`);\n }\n }\n \n if (this.svg) {\n this.svg.setAttribute('width', this.size);\n this.svg.setAttribute('height', this.size);\n this.svg.setAttribute('viewBox', `0 0 ${this.size} ${this.size}`);\n }\n \n this.renderProgress();\n }\n\n animateTo(targetValue, duration = 1000) {\n const startValue = this.value;\n const diff = targetValue - startValue;\n const startTime = performance.now();\n\n const animate = (currentTime) => {\n const elapsed = currentTime - startTime;\n const progress = Math.min(elapsed / duration, 1);\n\n // Ease-out function\n const easeProgress = 1 - Math.pow(1 - progress, 3);\n \n const newValue = startValue + (diff * easeProgress);\n this.setValue(newValue, false);\n\n if (progress < 1) {\n requestAnimationFrame(animate);\n } else {\n this.setValue(targetValue, false);\n }\n };\n\n requestAnimationFrame(animate);\n }\n\n pulse() {\n if (!this.containerElement) return;\n\n this.containerElement.style.animation = 'none';\n setTimeout(() => {\n this.containerElement.style.animation = 'circular-progress-pulse 0.5s ease-out';\n }, 10);\n\n setTimeout(() => {\n this.containerElement.style.animation = '';\n }, 500);\n }\n\n complete() {\n this.variant = 'success';\n this.applyVariant();\n this.setValue(this.max);\n this.pulse();\n }\n\n reset() {\n this.setValue(this.min);\n }\n\n hide() {\n if (this.element) {\n this.element.style.display = 'none';\n }\n }\n\n show() {\n if (this.element) {\n this.element.style.display = '';\n }\n }\n\n getValue() {\n return this.value;\n }\n\n getPercentageValue() {\n return this.getPercentage();\n }\n\n async onBeforeDestroy() {\n // Clean up popover\n if (this.popover) {\n this.popover.dispose();\n this.popover = null;\n }\n\n await super.onBeforeDestroy();\n }\n}\n"],"names":[],"mappings":"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"}
|