@dragonworks/ngx-dashboard-widgets 20.0.6 → 20.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/dragonworks-ngx-dashboard-widgets.mjs +2251 -0
- package/fesm2022/dragonworks-ngx-dashboard-widgets.mjs.map +1 -0
- package/index.d.ts +532 -0
- package/package.json +42 -31
- package/ng-package.json +0 -7
- package/src/lib/arrow-widget/arrow-state-dialog.component.ts +0 -187
- package/src/lib/arrow-widget/arrow-widget.component.html +0 -9
- package/src/lib/arrow-widget/arrow-widget.component.scss +0 -52
- package/src/lib/arrow-widget/arrow-widget.component.ts +0 -78
- package/src/lib/arrow-widget/arrow-widget.metadata.ts +0 -3
- package/src/lib/clock-widget/analog-clock/analog-clock.component.html +0 -66
- package/src/lib/clock-widget/analog-clock/analog-clock.component.scss +0 -103
- package/src/lib/clock-widget/analog-clock/analog-clock.component.ts +0 -120
- package/src/lib/clock-widget/clock-state-dialog.component.ts +0 -170
- package/src/lib/clock-widget/clock-widget.component.html +0 -16
- package/src/lib/clock-widget/clock-widget.component.scss +0 -160
- package/src/lib/clock-widget/clock-widget.component.ts +0 -87
- package/src/lib/clock-widget/clock-widget.metadata.ts +0 -42
- package/src/lib/clock-widget/digital-clock/__tests__/digital-clock.component.spec.ts +0 -276
- package/src/lib/clock-widget/digital-clock/digital-clock.component.html +0 -1
- package/src/lib/clock-widget/digital-clock/digital-clock.component.scss +0 -43
- package/src/lib/clock-widget/digital-clock/digital-clock.component.ts +0 -105
- package/src/lib/directives/__tests__/responsive-text.directive.spec.ts +0 -906
- package/src/lib/directives/responsive-text.directive.ts +0 -334
- package/src/lib/label-widget/__tests__/label-widget.component.spec.ts +0 -539
- package/src/lib/label-widget/label-state-dialog.component.ts +0 -385
- package/src/lib/label-widget/label-widget.component.html +0 -21
- package/src/lib/label-widget/label-widget.component.scss +0 -112
- package/src/lib/label-widget/label-widget.component.ts +0 -96
- package/src/lib/label-widget/label-widget.metadata.ts +0 -3
- package/src/public-api.ts +0 -7
- package/tsconfig.lib.json +0 -15
- package/tsconfig.lib.prod.json +0 -11
- package/tsconfig.spec.json +0 -14
package/index.d.ts
ADDED
|
@@ -0,0 +1,532 @@
|
|
|
1
|
+
import * as _angular_core from '@angular/core';
|
|
2
|
+
import { AfterViewInit } from '@angular/core';
|
|
3
|
+
import * as _angular_platform_browser from '@angular/platform-browser';
|
|
4
|
+
import { Widget, WidgetMetadata } from '@dragonworks/ngx-dashboard';
|
|
5
|
+
|
|
6
|
+
interface ArrowWidgetState {
|
|
7
|
+
direction: 'left' | 'up' | 'right' | 'down';
|
|
8
|
+
opacity?: number;
|
|
9
|
+
hasBackground?: boolean;
|
|
10
|
+
}
|
|
11
|
+
declare class ArrowWidgetComponent implements Widget {
|
|
12
|
+
#private;
|
|
13
|
+
static metadata: WidgetMetadata;
|
|
14
|
+
readonly safeSvgIcon: _angular_platform_browser.SafeHtml;
|
|
15
|
+
readonly state: _angular_core.WritableSignal<ArrowWidgetState>;
|
|
16
|
+
readonly rotationAngle: _angular_core.Signal<number>;
|
|
17
|
+
dashboardSetState(state?: unknown): void;
|
|
18
|
+
dashboardGetState(): ArrowWidgetState;
|
|
19
|
+
dashboardEditState(): void;
|
|
20
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<ArrowWidgetComponent, never>;
|
|
21
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<ArrowWidgetComponent, "ngx-dashboard-arrow-widget", never, {}, {}, never, never, true, never>;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
interface LabelWidgetState {
|
|
25
|
+
label: string;
|
|
26
|
+
fontSize?: number;
|
|
27
|
+
alignment?: 'left' | 'center' | 'right';
|
|
28
|
+
fontWeight?: 'normal' | 'bold';
|
|
29
|
+
opacity?: number;
|
|
30
|
+
hasBackground?: boolean;
|
|
31
|
+
responsive?: boolean;
|
|
32
|
+
minFontSize?: number;
|
|
33
|
+
maxFontSize?: number;
|
|
34
|
+
}
|
|
35
|
+
declare class LabelWidgetComponent implements Widget {
|
|
36
|
+
#private;
|
|
37
|
+
static metadata: WidgetMetadata;
|
|
38
|
+
safeSvgIcon: _angular_platform_browser.SafeHtml;
|
|
39
|
+
state: _angular_core.WritableSignal<LabelWidgetState>;
|
|
40
|
+
dashboardSetState(state?: unknown): void;
|
|
41
|
+
dashboardGetState(): LabelWidgetState;
|
|
42
|
+
dashboardEditState(): void;
|
|
43
|
+
get hasContent(): boolean;
|
|
44
|
+
get label(): string;
|
|
45
|
+
readonly minFontSize: _angular_core.Signal<number>;
|
|
46
|
+
readonly maxFontSize: _angular_core.Signal<number>;
|
|
47
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<LabelWidgetComponent, never>;
|
|
48
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<LabelWidgetComponent, "ngx-dashboard-label-widget", never, {}, {}, never, never, true, never>;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
interface ClockWidgetState {
|
|
52
|
+
mode: 'analog' | 'digital';
|
|
53
|
+
hasBackground?: boolean;
|
|
54
|
+
timeFormat?: '12h' | '24h';
|
|
55
|
+
showSeconds?: boolean;
|
|
56
|
+
}
|
|
57
|
+
declare class ClockWidgetComponent implements Widget {
|
|
58
|
+
#private;
|
|
59
|
+
static metadata: WidgetMetadata;
|
|
60
|
+
safeSvgIcon: _angular_platform_browser.SafeHtml;
|
|
61
|
+
state: _angular_core.WritableSignal<ClockWidgetState>;
|
|
62
|
+
constructor();
|
|
63
|
+
dashboardSetState(state?: unknown): void;
|
|
64
|
+
dashboardGetState(): ClockWidgetState;
|
|
65
|
+
dashboardEditState(): void;
|
|
66
|
+
get isAnalog(): boolean;
|
|
67
|
+
get isDigital(): boolean;
|
|
68
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<ClockWidgetComponent, never>;
|
|
69
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<ClockWidgetComponent, "ngx-dashboard-clock-widget", never, {}, {}, never, never, true, never>;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
interface RadialGaugeWidgetState {
|
|
73
|
+
value?: number;
|
|
74
|
+
colorProfile?: 'dynamic' | 'static';
|
|
75
|
+
active?: boolean;
|
|
76
|
+
hasBackground?: boolean;
|
|
77
|
+
showValueLabel?: boolean;
|
|
78
|
+
}
|
|
79
|
+
declare class RadialGaugeWidgetComponent implements Widget {
|
|
80
|
+
#private;
|
|
81
|
+
static metadata: WidgetMetadata;
|
|
82
|
+
readonly safeSvgIcon: _angular_platform_browser.SafeHtml;
|
|
83
|
+
readonly state: _angular_core.WritableSignal<RadialGaugeWidgetState>;
|
|
84
|
+
readonly segments: _angular_core.Signal<{
|
|
85
|
+
from: number;
|
|
86
|
+
to: number;
|
|
87
|
+
color: string;
|
|
88
|
+
}[]>;
|
|
89
|
+
dashboardSetState(state?: unknown): void;
|
|
90
|
+
dashboardGetState(): RadialGaugeWidgetState;
|
|
91
|
+
dashboardEditState(): void;
|
|
92
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<RadialGaugeWidgetComponent, never>;
|
|
93
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<RadialGaugeWidgetComponent, "ngx-dashboard-radial-gauge-widget", never, {}, {}, never, never, true, never>;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Directive that automatically adjusts font size to fit text within its parent container.
|
|
98
|
+
* Uses canvas-based measurement for performance and DOM verification for accuracy.
|
|
99
|
+
*
|
|
100
|
+
* @example
|
|
101
|
+
* <div class="container">
|
|
102
|
+
* <span responsiveText [minFontSize]="12" [maxFontSize]="72">Dynamic text here</span>
|
|
103
|
+
* </div>
|
|
104
|
+
*/
|
|
105
|
+
declare class ResponsiveTextDirective implements AfterViewInit {
|
|
106
|
+
/** Minimum font-size in pixels (accessibility floor) */
|
|
107
|
+
minFontSize: _angular_core.InputSignalWithTransform<number, unknown>;
|
|
108
|
+
/** Maximum font-size in pixels (layout ceiling) */
|
|
109
|
+
maxFontSize: _angular_core.InputSignalWithTransform<number, unknown>;
|
|
110
|
+
/**
|
|
111
|
+
* Line-height: pass a multiplier (e.g. 1.1) or absolute px value.
|
|
112
|
+
* For single-line text a multiplier < 10 is treated as unitless.
|
|
113
|
+
*/
|
|
114
|
+
lineHeight: _angular_core.InputSignalWithTransform<number, unknown>;
|
|
115
|
+
/** Whether to observe text mutations after first render */
|
|
116
|
+
observeMutations: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
117
|
+
/** Debounce delay in ms for resize/mutation callbacks */
|
|
118
|
+
debounceMs: _angular_core.InputSignalWithTransform<number, unknown>;
|
|
119
|
+
private readonly el;
|
|
120
|
+
private readonly zone;
|
|
121
|
+
private readonly platformId;
|
|
122
|
+
private readonly destroyRef;
|
|
123
|
+
private _ctx?;
|
|
124
|
+
private get ctx();
|
|
125
|
+
private ro?;
|
|
126
|
+
private mo?;
|
|
127
|
+
private fitTimeout?;
|
|
128
|
+
private lastText;
|
|
129
|
+
private lastMaxW;
|
|
130
|
+
private lastMaxH;
|
|
131
|
+
private lastFontSize;
|
|
132
|
+
constructor();
|
|
133
|
+
ngAfterViewInit(): void;
|
|
134
|
+
/**
|
|
135
|
+
* Debounced fit handler to prevent excessive recalculations
|
|
136
|
+
*/
|
|
137
|
+
private requestFit;
|
|
138
|
+
/**
|
|
139
|
+
* Recalculate & apply the ideal font-size
|
|
140
|
+
*/
|
|
141
|
+
private fit;
|
|
142
|
+
/**
|
|
143
|
+
* Calculate available space accounting for padding and borders
|
|
144
|
+
*/
|
|
145
|
+
private getAvailableSpace;
|
|
146
|
+
/**
|
|
147
|
+
* DOM-based verification to handle sub-pixel discrepancies
|
|
148
|
+
*/
|
|
149
|
+
private verifyFit;
|
|
150
|
+
/**
|
|
151
|
+
* Binary search for optimal font size using canvas measurements
|
|
152
|
+
*/
|
|
153
|
+
private calcFit;
|
|
154
|
+
/**
|
|
155
|
+
* Calculate text height from metrics
|
|
156
|
+
*/
|
|
157
|
+
private calculateTextHeight;
|
|
158
|
+
/**
|
|
159
|
+
* Observe parent container resizes
|
|
160
|
+
*/
|
|
161
|
+
private observeResize;
|
|
162
|
+
/**
|
|
163
|
+
* Observe text content changes
|
|
164
|
+
*/
|
|
165
|
+
private observeText;
|
|
166
|
+
/**
|
|
167
|
+
* Cleanup resources
|
|
168
|
+
*/
|
|
169
|
+
private cleanup;
|
|
170
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<ResponsiveTextDirective, never>;
|
|
171
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<ResponsiveTextDirective, "[libResponsiveText]", never, { "minFontSize": { "alias": "minFontSize"; "required": false; "isSignal": true; }; "maxFontSize": { "alias": "maxFontSize"; "required": false; "isSignal": true; }; "lineHeight": { "alias": "lineHeight"; "required": false; "isSignal": true; }; "observeMutations": { "alias": "observeMutations"; "required": false; "isSignal": true; }; "debounceMs": { "alias": "debounceMs"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
interface RadialGaugeSegment {
|
|
175
|
+
from: number;
|
|
176
|
+
to: number;
|
|
177
|
+
color: string;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Responsive radial gauge component with hybrid sizing and thickness control.
|
|
181
|
+
*
|
|
182
|
+
* This component provides a highly flexible gauge system with three independent
|
|
183
|
+
* control dimensions that can be mixed and matched for different use cases:
|
|
184
|
+
*
|
|
185
|
+
* ## Size Control:
|
|
186
|
+
* - **Fixed Size**: Use manual `size` input (traditional behavior)
|
|
187
|
+
* - **Container Responsive**: Enable `fitToContainer` for automatic sizing
|
|
188
|
+
*
|
|
189
|
+
* ## Thickness Control:
|
|
190
|
+
* - **Manual Thickness**: Use individual thickness inputs (traditional behavior)
|
|
191
|
+
* - **Proportional Thickness**: Enable `responsiveMode` for size-based scaling
|
|
192
|
+
*
|
|
193
|
+
* ## Usage Scenarios:
|
|
194
|
+
*
|
|
195
|
+
* ### 1. Dashboard Widgets (Recommended)
|
|
196
|
+
* ```html
|
|
197
|
+
* <ngx-radial-gauge
|
|
198
|
+
* [value]="cpuUsage"
|
|
199
|
+
* [fitToContainer]="true"
|
|
200
|
+
* [responsiveMode]="true"
|
|
201
|
+
* [sizeToThicknessRatio]="12" />
|
|
202
|
+
* ```
|
|
203
|
+
* **Best for**: Grid layouts, dashboard panels, adaptive containers
|
|
204
|
+
* **Behavior**: Automatically resizes to fit available space while maintaining
|
|
205
|
+
* consistent proportional appearance across all sizes.
|
|
206
|
+
*
|
|
207
|
+
* ### 2. Fixed Layouts (Traditional)
|
|
208
|
+
* ```html
|
|
209
|
+
* <ngx-radial-gauge
|
|
210
|
+
* [value]="temperature"
|
|
211
|
+
* [size]="300"
|
|
212
|
+
* [outerThickness]="36"
|
|
213
|
+
* [innerThickness]="12" />
|
|
214
|
+
* ```
|
|
215
|
+
* **Best for**: Static designs, precise sizing requirements, print layouts
|
|
216
|
+
* **Behavior**: Exact pixel control over all dimensions, predictable appearance.
|
|
217
|
+
*
|
|
218
|
+
* ### 3. Scalable Designs
|
|
219
|
+
* ```html
|
|
220
|
+
* <ngx-radial-gauge
|
|
221
|
+
* [value]="batteryLevel"
|
|
222
|
+
* [size]="gaugeSize"
|
|
223
|
+
* [responsiveMode]="true"
|
|
224
|
+
* [sizeToThicknessRatio]="20" />
|
|
225
|
+
* ```
|
|
226
|
+
* **Best for**: User-configurable sizing, responsive breakpoints, zoom interfaces
|
|
227
|
+
* **Behavior**: Manual size control with automatic thickness scaling. As size
|
|
228
|
+
* increases/decreases, ring thickness scales proportionally to maintain visual balance.
|
|
229
|
+
*
|
|
230
|
+
* ## Mathematical Relationships:
|
|
231
|
+
*
|
|
232
|
+
* When `responsiveMode=true`, thickness follows this formula:
|
|
233
|
+
* ```
|
|
234
|
+
* baseThickness = effectiveSize / sizeToThicknessRatio
|
|
235
|
+
* outerThickness = baseThickness × responsiveProportions.outer (default: 3)
|
|
236
|
+
* innerThickness = baseThickness × responsiveProportions.inner (default: 1)
|
|
237
|
+
* gap = baseThickness × responsiveProportions.gap (default: 0.5)
|
|
238
|
+
* totalThickness = baseThickness × 4.5 (outer + inner + gap)
|
|
239
|
+
* ```
|
|
240
|
+
*
|
|
241
|
+
* Example with 300px gauge and ratio=20 (ultra-thin):
|
|
242
|
+
* - baseThickness = 15px
|
|
243
|
+
* - outerThickness = 45px (15×3)
|
|
244
|
+
* - innerThickness = 15px (15×1)
|
|
245
|
+
* - gap = 7.5px (15×0.5)
|
|
246
|
+
* - totalThickness = 67.5px (22.5% of diameter)
|
|
247
|
+
*
|
|
248
|
+
* ## Container Responsiveness:
|
|
249
|
+
*
|
|
250
|
+
* When `fitToContainer=true`, the component uses ResizeObserver to:
|
|
251
|
+
* 1. Monitor parent container dimension changes
|
|
252
|
+
* 2. Calculate maximum diameter maintaining 2:1 aspect ratio (width:height)
|
|
253
|
+
* 3. Apply containerPadding for safe margins
|
|
254
|
+
* 4. Update gauge size in real-time
|
|
255
|
+
*
|
|
256
|
+
* This provides true responsive behavior for dashboard widgets, grid layouts,
|
|
257
|
+
* and adaptive interfaces.
|
|
258
|
+
*
|
|
259
|
+
* ## Accessibility:
|
|
260
|
+
*
|
|
261
|
+
* The component implements ARIA meter role with proper labeling:
|
|
262
|
+
* - `role="meter"` for semantic meaning
|
|
263
|
+
* - `aria-valuemin/max/now` for screen readers
|
|
264
|
+
* - `aria-label` with contextual information
|
|
265
|
+
* - Internationalized number formatting
|
|
266
|
+
*
|
|
267
|
+
*/
|
|
268
|
+
declare class RadialGaugeComponent {
|
|
269
|
+
private readonly valueTextEl;
|
|
270
|
+
private readonly valueGroupEl;
|
|
271
|
+
private readonly refTextEl;
|
|
272
|
+
readonly value: _angular_core.InputSignal<number>;
|
|
273
|
+
readonly min: _angular_core.InputSignal<number>;
|
|
274
|
+
readonly max: _angular_core.InputSignal<number>;
|
|
275
|
+
readonly segments: _angular_core.InputSignal<RadialGaugeSegment[] | undefined>;
|
|
276
|
+
readonly title: _angular_core.InputSignal<string>;
|
|
277
|
+
readonly description: _angular_core.InputSignal<string>;
|
|
278
|
+
readonly segmentGapPx: _angular_core.InputSignal<number>;
|
|
279
|
+
/**
|
|
280
|
+
* Whether the gauge should display with a background.
|
|
281
|
+
* Affects text color contrast and other visual elements.
|
|
282
|
+
* @default false
|
|
283
|
+
*/
|
|
284
|
+
readonly hasBackground: _angular_core.InputSignal<boolean>;
|
|
285
|
+
/**
|
|
286
|
+
* Whether to display the numeric value label in the center of the gauge.
|
|
287
|
+
* @default true
|
|
288
|
+
*/
|
|
289
|
+
readonly showValueLabel: _angular_core.InputSignal<boolean>;
|
|
290
|
+
/**
|
|
291
|
+
* Base gauge diameter in pixels. Used as fallback when fitToContainer is false.
|
|
292
|
+
* @default 300
|
|
293
|
+
*/
|
|
294
|
+
readonly size: _angular_core.InputSignal<number>;
|
|
295
|
+
/**
|
|
296
|
+
* Automatically resize gauge to fit its container dimensions.
|
|
297
|
+
* When true, the gauge will observe container size changes and adjust accordingly.
|
|
298
|
+
* Maintains semicircle aspect ratio (2:1 width:height).
|
|
299
|
+
* @default false
|
|
300
|
+
*/
|
|
301
|
+
readonly fitToContainer: _angular_core.InputSignal<boolean>;
|
|
302
|
+
/**
|
|
303
|
+
* Padding in pixels to maintain from container edges when fitToContainer is true.
|
|
304
|
+
* @default 10
|
|
305
|
+
*/
|
|
306
|
+
readonly containerPadding: _angular_core.InputSignal<number>;
|
|
307
|
+
/**
|
|
308
|
+
* Use proportional thickness scaling based on gauge size.
|
|
309
|
+
* When true, all thickness values are calculated as multiples of baseThickness.
|
|
310
|
+
* Overrides manual outerThickness, innerThickness, and gap inputs.
|
|
311
|
+
* @default false
|
|
312
|
+
*/
|
|
313
|
+
readonly responsiveMode: _angular_core.InputSignal<boolean>;
|
|
314
|
+
/**
|
|
315
|
+
* Ratio used to calculate base thickness from gauge size.
|
|
316
|
+
* baseThickness = effectiveSize / sizeToThicknessRatio
|
|
317
|
+
* Higher values create thinner gauge rings for ultra-thin appearance.
|
|
318
|
+
* @default 20
|
|
319
|
+
* @example
|
|
320
|
+
* - ratio=15: thicker rings (bt = size/15)
|
|
321
|
+
* - ratio=20: ultra-thin balanced appearance (bt = size/20)
|
|
322
|
+
* - ratio=30: extremely thin rings (bt = size/30)
|
|
323
|
+
*/
|
|
324
|
+
readonly sizeToThicknessRatio: _angular_core.InputSignal<number>;
|
|
325
|
+
/**
|
|
326
|
+
* Proportional multipliers for responsive thickness calculations.
|
|
327
|
+
* - outer: Multiplier for outer ring thickness (default: 3)
|
|
328
|
+
* - inner: Multiplier for inner ring thickness (default: 1)
|
|
329
|
+
* - gap: Multiplier for gap between rings (default: 0.5)
|
|
330
|
+
* Total thickness = baseThickness × (outer + inner + gap) = bt × 4.5
|
|
331
|
+
* @default { outer: 3, inner: 1, gap: 0.5 }
|
|
332
|
+
*/
|
|
333
|
+
readonly responsiveProportions: _angular_core.InputSignal<{
|
|
334
|
+
outer: number;
|
|
335
|
+
inner: number;
|
|
336
|
+
gap: number;
|
|
337
|
+
}>;
|
|
338
|
+
/**
|
|
339
|
+
* Manual outer ring thickness in pixels. Ignored when responsiveMode is true.
|
|
340
|
+
* @default 36
|
|
341
|
+
*/
|
|
342
|
+
readonly outerThickness: _angular_core.InputSignal<number>;
|
|
343
|
+
/**
|
|
344
|
+
* Manual inner ring thickness in pixels. Ignored when responsiveMode is true.
|
|
345
|
+
* @default 12
|
|
346
|
+
*/
|
|
347
|
+
readonly innerThickness: _angular_core.InputSignal<number>;
|
|
348
|
+
/**
|
|
349
|
+
* Manual gap between rings in pixels. Ignored when responsiveMode is true.
|
|
350
|
+
* @default 8
|
|
351
|
+
*/
|
|
352
|
+
readonly gap: _angular_core.InputSignal<number>;
|
|
353
|
+
readonly titleId: string;
|
|
354
|
+
readonly descId: string;
|
|
355
|
+
readonly clipId: string;
|
|
356
|
+
private readonly locale;
|
|
357
|
+
private readonly elementRef;
|
|
358
|
+
private readonly destroyRef;
|
|
359
|
+
private readonly nf;
|
|
360
|
+
/**
|
|
361
|
+
* Tracks the container's available size for responsive sizing.
|
|
362
|
+
* Updated by ResizeObserver when fitToContainer is enabled.
|
|
363
|
+
* @private
|
|
364
|
+
*/
|
|
365
|
+
private readonly containerSize;
|
|
366
|
+
/**
|
|
367
|
+
* ResizeObserver instance for monitoring container size changes.
|
|
368
|
+
* Created when fitToContainer is enabled, destroyed on component cleanup.
|
|
369
|
+
* @private
|
|
370
|
+
*/
|
|
371
|
+
private resizeObserver;
|
|
372
|
+
readonly viewReady: _angular_core.Signal<boolean>;
|
|
373
|
+
readonly fontsReady: _angular_core.Signal<boolean>;
|
|
374
|
+
constructor();
|
|
375
|
+
/**
|
|
376
|
+
* Effect that manages ResizeObserver lifecycle based on fitToContainer input.
|
|
377
|
+
* Automatically connects/disconnects observer when the input changes.
|
|
378
|
+
* @private
|
|
379
|
+
*/
|
|
380
|
+
private readonly containerObserverEffect;
|
|
381
|
+
referenceString: _angular_core.Signal<string>;
|
|
382
|
+
valueTransform: _angular_core.Signal<string>;
|
|
383
|
+
/** Guarded getBBox that avoids 0/NaN on detached or invisible nodes. */
|
|
384
|
+
safeBBox(node: SVGGraphicsElement): DOMRect;
|
|
385
|
+
/**
|
|
386
|
+
* The effective gauge diameter, accounting for container sizing and manual size input.
|
|
387
|
+
* Priority: containerSize (when fitToContainer=true) > manual size input
|
|
388
|
+
* @returns Effective diameter in pixels
|
|
389
|
+
*
|
|
390
|
+
* @example
|
|
391
|
+
* // Fixed size mode
|
|
392
|
+
* fitToContainer=false, size=300 → effectiveSize=300
|
|
393
|
+
*
|
|
394
|
+
* // Container responsive mode
|
|
395
|
+
* fitToContainer=true, container=400px wide → effectiveSize=380 (minus padding)
|
|
396
|
+
*/
|
|
397
|
+
private readonly effectiveSize;
|
|
398
|
+
/**
|
|
399
|
+
* Base thickness calculated from effective size for proportional scaling.
|
|
400
|
+
* Only used when responsiveMode is enabled.
|
|
401
|
+
* Formula: baseThickness = effectiveSize / sizeToThicknessRatio
|
|
402
|
+
* @returns Base thickness in pixels, or 0 when responsiveMode is false
|
|
403
|
+
*
|
|
404
|
+
* @example
|
|
405
|
+
* // effectiveSize=300, sizeToThicknessRatio=12
|
|
406
|
+
* baseThickness = 300/12 = 25px
|
|
407
|
+
* // Total ring thickness = 25 × 4.5 = 112.5px (37.5% of diameter)
|
|
408
|
+
*/
|
|
409
|
+
private readonly baseThickness;
|
|
410
|
+
/**
|
|
411
|
+
* Effective outer ring thickness, supporting both manual and responsive modes.
|
|
412
|
+
* - Responsive mode: baseThickness × responsiveProportions.outer
|
|
413
|
+
* - Manual mode: outerThickness input value
|
|
414
|
+
* @returns Outer ring thickness in pixels
|
|
415
|
+
*/
|
|
416
|
+
readonly effectiveOuterThickness: _angular_core.Signal<number>;
|
|
417
|
+
/**
|
|
418
|
+
* Effective inner ring thickness, supporting both manual and responsive modes.
|
|
419
|
+
* - Responsive mode: baseThickness × responsiveProportions.inner
|
|
420
|
+
* - Manual mode: innerThickness input value
|
|
421
|
+
* @returns Inner ring thickness in pixels
|
|
422
|
+
*/
|
|
423
|
+
readonly effectiveInnerThickness: _angular_core.Signal<number>;
|
|
424
|
+
/**
|
|
425
|
+
* Effective gap between rings, supporting both manual and responsive modes.
|
|
426
|
+
* - Responsive mode: baseThickness × responsiveProportions.gap
|
|
427
|
+
* - Manual mode: gap input value
|
|
428
|
+
* @returns Gap between rings in pixels
|
|
429
|
+
*/
|
|
430
|
+
readonly effectiveGap: _angular_core.Signal<number>;
|
|
431
|
+
private readonly svgPadding;
|
|
432
|
+
readonly svgWidth: _angular_core.Signal<number>;
|
|
433
|
+
readonly svgHeight: _angular_core.Signal<number>;
|
|
434
|
+
readonly centerX: _angular_core.Signal<number>;
|
|
435
|
+
readonly centerY: _angular_core.Signal<number>;
|
|
436
|
+
/**
|
|
437
|
+
* If a string is provided, we measure it and allocate space for that width.
|
|
438
|
+
* If a number is provided, we build a string of that many `referenceGlyph`s.
|
|
439
|
+
* If omitted, we fall back to measuring the actual label.
|
|
440
|
+
*/
|
|
441
|
+
labelReference: _angular_core.InputSignal<string | number | undefined>;
|
|
442
|
+
/** Glyph to repeat when labelReference is a number (defaults to '0'). */
|
|
443
|
+
referenceGlyph: _angular_core.InputSignal<string>;
|
|
444
|
+
/** Extra breathing room inside the inner semicircle box (in px). */
|
|
445
|
+
labelPadding: _angular_core.InputSignal<number>;
|
|
446
|
+
/** Safety multiplier to avoid clipping ascenders/descenders. */
|
|
447
|
+
baselineSafety: _angular_core.InputSignal<number>;
|
|
448
|
+
readonly outerRadius: _angular_core.Signal<number>;
|
|
449
|
+
readonly innerRadius: _angular_core.Signal<number>;
|
|
450
|
+
readonly legendOuterRadius: _angular_core.Signal<number>;
|
|
451
|
+
readonly legendInnerRadius: _angular_core.Signal<number>;
|
|
452
|
+
private readonly startAngle;
|
|
453
|
+
private readonly endAngle;
|
|
454
|
+
readonly clampedValue: _angular_core.Signal<number>;
|
|
455
|
+
readonly percentage: _angular_core.Signal<number>;
|
|
456
|
+
readonly percent: _angular_core.Signal<number>;
|
|
457
|
+
private readonly defaultSegments;
|
|
458
|
+
readonly actualSegments: _angular_core.Signal<RadialGaugeSegment[]>;
|
|
459
|
+
readonly formattedLabel: _angular_core.Signal<string>;
|
|
460
|
+
readonly valueColor: _angular_core.Signal<string>;
|
|
461
|
+
readonly backgroundArcPath: _angular_core.Signal<string>;
|
|
462
|
+
readonly segmentPaths: _angular_core.Signal<{
|
|
463
|
+
path: string;
|
|
464
|
+
color: string;
|
|
465
|
+
}[]>;
|
|
466
|
+
readonly ariaLabel: _angular_core.Signal<string>;
|
|
467
|
+
private clamp;
|
|
468
|
+
/**
|
|
469
|
+
* Converts a percentage (0-1) to an angle position on the gauge arc.
|
|
470
|
+
* The gauge spans from startAngle (-180°) to endAngle (0°), creating a semicircle.
|
|
471
|
+
* @param p - Percentage value between 0 and 1
|
|
472
|
+
* @returns Angle in degrees for the given percentage along the gauge arc
|
|
473
|
+
* @example
|
|
474
|
+
* angleForPercentage(0) => -180° (start of gauge)
|
|
475
|
+
* angleForPercentage(0.5) => -90° (middle of gauge)
|
|
476
|
+
* angleForPercentage(1) => 0° (end of gauge)
|
|
477
|
+
*/
|
|
478
|
+
private angleForPercentage;
|
|
479
|
+
/**
|
|
480
|
+
* Converts polar coordinates (radius, angle) to Cartesian coordinates (x, y).
|
|
481
|
+
* Uses standard trigonometric conversion where angle 0° points to the right (3 o'clock).
|
|
482
|
+
* @param cx - Center X coordinate of the circle
|
|
483
|
+
* @param cy - Center Y coordinate of the circle
|
|
484
|
+
* @param r - Radius distance from center
|
|
485
|
+
* @param angle - Angle in degrees (0° = right, 90° = down, 180° = left, -90° = up)
|
|
486
|
+
* @returns Object with x and y Cartesian coordinates
|
|
487
|
+
* @example
|
|
488
|
+
* polarToCartesian(100, 100, 50, 0) => {x: 150, y: 100} // 3 o'clock
|
|
489
|
+
* polarToCartesian(100, 100, 50, -90) => {x: 100, y: 50} // 12 o'clock
|
|
490
|
+
*/
|
|
491
|
+
private polarToCartesian;
|
|
492
|
+
/**
|
|
493
|
+
* Creates an SVG path string for a circular arc segment.
|
|
494
|
+
* Uses SVG arc path commands to draw an arc from start angle to end angle.
|
|
495
|
+
* @param r - Radius of the arc
|
|
496
|
+
* @param a0 - Starting angle in degrees
|
|
497
|
+
* @param a1 - Ending angle in degrees
|
|
498
|
+
* @returns SVG path string defining the arc
|
|
499
|
+
* @example
|
|
500
|
+
* createArcPath(50, -180, 0) => "M cx-50 cy A 50 50 0 1 1 cx+50 cy"
|
|
501
|
+
* This creates a semicircle from left (-180°) to right (0°)
|
|
502
|
+
*
|
|
503
|
+
* SVG Arc Parameters:
|
|
504
|
+
* - rx, ry: Radii (equal for circular arc)
|
|
505
|
+
* - x-axis-rotation: 0 (no rotation for circles)
|
|
506
|
+
* - large-arc-flag: 1 if arc > 180°, 0 otherwise
|
|
507
|
+
* - sweep-flag: 1 for clockwise, 0 for counter-clockwise
|
|
508
|
+
*/
|
|
509
|
+
private createArcPath;
|
|
510
|
+
/**
|
|
511
|
+
* Calculates the angular gap in degrees needed for a specific pixel gap at a given radius.
|
|
512
|
+
* Used to create visual separation between legend segments.
|
|
513
|
+
* @param px - Desired gap size in pixels
|
|
514
|
+
* @param r - Radius at which the gap will appear
|
|
515
|
+
* @returns Gap size in degrees, clamped between 0° and 180°
|
|
516
|
+
* @example
|
|
517
|
+
* For a 4px gap on a radius of 100px:
|
|
518
|
+
* Arc length = π * 100 = 314.16px (semicircle)
|
|
519
|
+
* Degrees = 180 * (4 / 314.16) ≈ 2.3°
|
|
520
|
+
*
|
|
521
|
+
* Mathematical basis:
|
|
522
|
+
* - Semicircle arc length = π * r
|
|
523
|
+
* - Ratio of gap to semicircle = px / (π * r)
|
|
524
|
+
* - Convert ratio to degrees by multiplying by 180°
|
|
525
|
+
*/
|
|
526
|
+
private gapDegreesForRadius;
|
|
527
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<RadialGaugeComponent, never>;
|
|
528
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<RadialGaugeComponent, "ngx-radial-gauge", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; "min": { "alias": "min"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "segments": { "alias": "segments"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": false; "isSignal": true; }; "description": { "alias": "description"; "required": false; "isSignal": true; }; "segmentGapPx": { "alias": "segmentGapPx"; "required": false; "isSignal": true; }; "hasBackground": { "alias": "hasBackground"; "required": false; "isSignal": true; }; "showValueLabel": { "alias": "showValueLabel"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "fitToContainer": { "alias": "fitToContainer"; "required": false; "isSignal": true; }; "containerPadding": { "alias": "containerPadding"; "required": false; "isSignal": true; }; "responsiveMode": { "alias": "responsiveMode"; "required": false; "isSignal": true; }; "sizeToThicknessRatio": { "alias": "sizeToThicknessRatio"; "required": false; "isSignal": true; }; "responsiveProportions": { "alias": "responsiveProportions"; "required": false; "isSignal": true; }; "outerThickness": { "alias": "outerThickness"; "required": false; "isSignal": true; }; "innerThickness": { "alias": "innerThickness"; "required": false; "isSignal": true; }; "gap": { "alias": "gap"; "required": false; "isSignal": true; }; "labelReference": { "alias": "labelReference"; "required": false; "isSignal": true; }; "referenceGlyph": { "alias": "referenceGlyph"; "required": false; "isSignal": true; }; "labelPadding": { "alias": "labelPadding"; "required": false; "isSignal": true; }; "baselineSafety": { "alias": "baselineSafety"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
export { ArrowWidgetComponent, ClockWidgetComponent, LabelWidgetComponent, RadialGaugeComponent, RadialGaugeWidgetComponent, ResponsiveTextDirective };
|
|
532
|
+
export type { ArrowWidgetState, ClockWidgetState, LabelWidgetState, RadialGaugeSegment, RadialGaugeWidgetState };
|
package/package.json
CHANGED
|
@@ -1,31 +1,42 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@dragonworks/ngx-dashboard-widgets",
|
|
3
|
-
"version": "20.
|
|
4
|
-
"description": "Widget collection for ngx-dashboard with Material Design 3 compliance including arrow, label, clock widgets and responsive text directive",
|
|
5
|
-
"peerDependencies": {
|
|
6
|
-
"@angular/common": "^20.
|
|
7
|
-
"@angular/core": "^20.
|
|
8
|
-
"@dragonworks/ngx-dashboard": "^20.0.0"
|
|
9
|
-
},
|
|
10
|
-
"dependencies": {
|
|
11
|
-
"tslib": "^2.3.0"
|
|
12
|
-
},
|
|
13
|
-
"sideEffects": false,
|
|
14
|
-
"repository": {
|
|
15
|
-
"type": "git",
|
|
16
|
-
"url": "git+https://github.com/TobyBackstrom/ngx-dashboard.git"
|
|
17
|
-
},
|
|
18
|
-
"author": "Toby Backstrom",
|
|
19
|
-
"license": "MIT",
|
|
20
|
-
"bugs": {
|
|
21
|
-
"url": "https://github.com/TobyBackstrom/ngx-dashboard/issues"
|
|
22
|
-
},
|
|
23
|
-
"homepage": "https://dragonworks.dev",
|
|
24
|
-
"keywords": [
|
|
25
|
-
"angular",
|
|
26
|
-
"dashboard",
|
|
27
|
-
"widgets",
|
|
28
|
-
"material-design",
|
|
29
|
-
"md3"
|
|
30
|
-
]
|
|
31
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "@dragonworks/ngx-dashboard-widgets",
|
|
3
|
+
"version": "20.1.1",
|
|
4
|
+
"description": "Widget collection for ngx-dashboard with Material Design 3 compliance including arrow, label, clock widgets and responsive text directive",
|
|
5
|
+
"peerDependencies": {
|
|
6
|
+
"@angular/common": "^20.2.0",
|
|
7
|
+
"@angular/core": "^20.2.0",
|
|
8
|
+
"@dragonworks/ngx-dashboard": "^20.0.0"
|
|
9
|
+
},
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"tslib": "^2.3.0"
|
|
12
|
+
},
|
|
13
|
+
"sideEffects": false,
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "git+https://github.com/TobyBackstrom/ngx-dashboard.git"
|
|
17
|
+
},
|
|
18
|
+
"author": "Toby Backstrom",
|
|
19
|
+
"license": "MIT",
|
|
20
|
+
"bugs": {
|
|
21
|
+
"url": "https://github.com/TobyBackstrom/ngx-dashboard/issues"
|
|
22
|
+
},
|
|
23
|
+
"homepage": "https://dragonworks.dev",
|
|
24
|
+
"keywords": [
|
|
25
|
+
"angular",
|
|
26
|
+
"dashboard",
|
|
27
|
+
"widgets",
|
|
28
|
+
"material-design",
|
|
29
|
+
"md3"
|
|
30
|
+
],
|
|
31
|
+
"module": "fesm2022/dragonworks-ngx-dashboard-widgets.mjs",
|
|
32
|
+
"typings": "index.d.ts",
|
|
33
|
+
"exports": {
|
|
34
|
+
"./package.json": {
|
|
35
|
+
"default": "./package.json"
|
|
36
|
+
},
|
|
37
|
+
".": {
|
|
38
|
+
"types": "./index.d.ts",
|
|
39
|
+
"default": "./fesm2022/dragonworks-ngx-dashboard-widgets.mjs"
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|