@rivet-health/design-system 2.3.1 → 2.5.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.
@@ -1,13 +1,13 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Component, ChangeDetectionStrategy, Input, HostBinding, Injectable, EventEmitter, ViewChild, Output, Directive, NgModule } from '@angular/core';
2
+ import { Component, ChangeDetectionStrategy, Input, HostBinding, Pipe, Injectable, EventEmitter, ViewChild, Output, Directive, HostListener, ViewContainerRef, NgModule } from '@angular/core';
3
3
  import * as i1 from '@angular/common';
4
- import { DecimalPipe, CommonModule } from '@angular/common';
5
- import { BehaviorSubject, map, shareReplay, combineLatest } from 'rxjs';
6
- import { pie, arc, line, stack } from 'd3-shape';
7
- import { scaleLinear, scaleBand } from 'd3-scale';
8
- import { timeYear, timeMonth, timeWeek, timeDay } from 'd3-time';
9
- import { timeFormat } from 'd3-time-format';
4
+ import { DecimalPipe, PercentPipe, CurrencyPipe, CommonModule } from '@angular/common';
5
+ import { BehaviorSubject, combineLatest, map, shareReplay } from 'rxjs';
6
+ import { pie, arc, stack, line } from 'd3-shape';
10
7
  import { index } from 'd3-array';
8
+ import { scaleBand, scaleLinear } from 'd3-scale';
9
+ import { timeMonth, timeYear, timeWeek, timeDay } from 'd3-time';
10
+ import { timeFormat } from 'd3-time-format';
11
11
 
12
12
  /**
13
13
  * DOM cache that clones existing elements if available.
@@ -362,6 +362,87 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
362
362
  type: Input
363
363
  }] } });
364
364
 
365
+ class DaysPipe {
366
+ constructor() {
367
+ this.inner = new DecimalPipe('en-us');
368
+ }
369
+ transform(value, digitsInfo) {
370
+ const ret = this.inner.transform(value, digitsInfo !== null && digitsInfo !== void 0 ? digitsInfo : '1.0-2');
371
+ return ret ? ret + (value === 1 ? ' day' : ' days') : '-';
372
+ }
373
+ }
374
+ DaysPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: DaysPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
375
+ DaysPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "14.3.0", ngImport: i0, type: DaysPipe, name: "rivDays" });
376
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: DaysPipe, decorators: [{
377
+ type: Pipe,
378
+ args: [{ name: 'rivDays' }]
379
+ }] });
380
+
381
+ class NumberPipe {
382
+ constructor() {
383
+ this.inner = new DecimalPipe('en-us');
384
+ }
385
+ transform(value, digitsInfo) {
386
+ var _a;
387
+ return (_a = this.inner.transform(value, digitsInfo !== null && digitsInfo !== void 0 ? digitsInfo : '1.0-0')) !== null && _a !== void 0 ? _a : '-';
388
+ }
389
+ }
390
+ NumberPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NumberPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
391
+ NumberPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "14.3.0", ngImport: i0, type: NumberPipe, name: "rivNumber" });
392
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NumberPipe, decorators: [{
393
+ type: Pipe,
394
+ args: [{ name: 'rivNumber' }]
395
+ }] });
396
+
397
+ class PercentagePipe {
398
+ constructor() {
399
+ this.inner = new PercentPipe('en-us');
400
+ }
401
+ transform(value, digitsInfo) {
402
+ var _a;
403
+ return (_a = this.inner.transform(value, digitsInfo !== null && digitsInfo !== void 0 ? digitsInfo : '1.1-1')) !== null && _a !== void 0 ? _a : '-';
404
+ }
405
+ }
406
+ PercentagePipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PercentagePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
407
+ PercentagePipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "14.3.0", ngImport: i0, type: PercentagePipe, name: "rivPercentage" });
408
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PercentagePipe, decorators: [{
409
+ type: Pipe,
410
+ args: [{ name: 'rivPercentage' }]
411
+ }] });
412
+
413
+ class SmallCurrencyPipe {
414
+ constructor() {
415
+ this.inner = new CurrencyPipe('en-us');
416
+ }
417
+ transform(value, digitsInfo) {
418
+ var _a, _b, _c, _d, _e;
419
+ if (value === null) {
420
+ return '-';
421
+ }
422
+ const num = typeof value == 'string' ? Number.parseFloat(value) : value;
423
+ const magnitude = Math.log10(Math.abs(num));
424
+ if (num === 0) {
425
+ return ((_a = this.inner.transform(num, undefined, undefined, digitsInfo !== null && digitsInfo !== void 0 ? digitsInfo : '1.0-0')) !== null && _a !== void 0 ? _a : '-');
426
+ }
427
+ if (magnitude >= 9) {
428
+ return (((_b = this.inner.transform(num / 1000000000, undefined, undefined, (digitsInfo !== null && digitsInfo !== void 0 ? digitsInfo : num / 1000000000 >= 100) ? '1.0-0' : '1.0-2')) !== null && _b !== void 0 ? _b : '-') + 'B');
429
+ }
430
+ if (magnitude >= 6) {
431
+ return (((_c = this.inner.transform(num / 1000000, undefined, undefined, (digitsInfo !== null && digitsInfo !== void 0 ? digitsInfo : num / 1000000 >= 100) ? '1.0-0' : '1.0-2')) !== null && _c !== void 0 ? _c : '-') + 'M');
432
+ }
433
+ if (magnitude >= 3) {
434
+ return (((_d = this.inner.transform(num / 1000, undefined, undefined, (digitsInfo !== null && digitsInfo !== void 0 ? digitsInfo : num / 1000 >= 100) ? '1.0-0' : '1.0-2')) !== null && _d !== void 0 ? _d : '-') + 'K');
435
+ }
436
+ return ((_e = this.inner.transform(num, undefined, undefined, (digitsInfo !== null && digitsInfo !== void 0 ? digitsInfo : num >= 100) ? '1.0-0' : '1.0-2')) !== null && _e !== void 0 ? _e : '-');
437
+ }
438
+ }
439
+ SmallCurrencyPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: SmallCurrencyPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
440
+ SmallCurrencyPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "14.3.0", ngImport: i0, type: SmallCurrencyPipe, name: "rivSmallCurrency" });
441
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: SmallCurrencyPipe, decorators: [{
442
+ type: Pipe,
443
+ args: [{ name: 'rivSmallCurrency' }]
444
+ }] });
445
+
365
446
  class CalloutService {
366
447
  constructor() {
367
448
  this.calloutStack$ = new BehaviorSubject([]);
@@ -594,6 +675,161 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
594
675
  }]
595
676
  }], ctorParameters: function () { return [{ type: i0.TemplateRef }, { type: CalloutService }]; } });
596
677
 
678
+ class TooltipComponent {
679
+ constructor() {
680
+ this.anchor = null;
681
+ this.theme = 'dark';
682
+ this.onMouseEnter = new EventEmitter();
683
+ this.onMouseLeave = new EventEmitter();
684
+ this.isTemplate = isTemplate;
685
+ }
686
+ _onMouseLeave(evt) {
687
+ this.onMouseLeave.emit(evt);
688
+ }
689
+ _onMouseEnter(evt) {
690
+ this.onMouseEnter.emit(evt);
691
+ }
692
+ }
693
+ TooltipComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: TooltipComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
694
+ TooltipComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: TooltipComponent, selector: "riv-tooltip", inputs: { anchor: "anchor", content: "content", theme: "theme" }, outputs: { onMouseEnter: "onMouseEnter", onMouseLeave: "onMouseLeave" }, host: { listeners: { "mouseleave": "_onMouseLeave()", "mouseenter": "_onMouseEnter()" } }, ngImport: i0, template: "<riv-callout\n [anchor]=\"anchor\"\n [preferredPosition]=\"'top-center'\"\n [allowedPositions]=\"[\n 'top-center',\n 'center-right',\n 'bottom-center',\n 'center-left'\n ]\"\n [isModal]=\"false\"\n [theme]=\"theme\"\n>\n <div class=\"content\">\n <ng-container *ngIf=\"content && isTemplate(content); else stringContent\">\n <ng-container *ngTemplateOutlet=\"content\"></ng-container>\n </ng-container>\n <ng-template #stringContent>\n {{ content }}\n </ng-template>\n </div>\n</riv-callout>\n", styles: [".content{padding:var(--size-xsmall) var(--size-small)}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: CalloutComponent, selector: "riv-callout", inputs: ["anchor", "isModal", "preferredPosition", "allowedPositions", "fallbackDirection", "showCaret", "theme"], outputs: ["close"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
695
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: TooltipComponent, decorators: [{
696
+ type: Component,
697
+ args: [{ selector: 'riv-tooltip', changeDetection: ChangeDetectionStrategy.OnPush, template: "<riv-callout\n [anchor]=\"anchor\"\n [preferredPosition]=\"'top-center'\"\n [allowedPositions]=\"[\n 'top-center',\n 'center-right',\n 'bottom-center',\n 'center-left'\n ]\"\n [isModal]=\"false\"\n [theme]=\"theme\"\n>\n <div class=\"content\">\n <ng-container *ngIf=\"content && isTemplate(content); else stringContent\">\n <ng-container *ngTemplateOutlet=\"content\"></ng-container>\n </ng-container>\n <ng-template #stringContent>\n {{ content }}\n </ng-template>\n </div>\n</riv-callout>\n", styles: [".content{padding:var(--size-xsmall) var(--size-small)}\n"] }]
698
+ }], propDecorators: { anchor: [{
699
+ type: Input
700
+ }], content: [{
701
+ type: Input
702
+ }], theme: [{
703
+ type: Input
704
+ }], onMouseEnter: [{
705
+ type: Output
706
+ }], onMouseLeave: [{
707
+ type: Output
708
+ }], _onMouseLeave: [{
709
+ type: HostListener,
710
+ args: ['mouseleave']
711
+ }], _onMouseEnter: [{
712
+ type: HostListener,
713
+ args: ['mouseenter']
714
+ }] } });
715
+ function isTemplate(v) {
716
+ return typeof v !== 'string';
717
+ }
718
+
719
+ class TooltipDirective {
720
+ constructor(el, applicationRef) {
721
+ this.el = el;
722
+ this.applicationRef = applicationRef;
723
+ this.rivTooltipTheme = 'dark';
724
+ this.closeDelay = 100;
725
+ }
726
+ onMouseEnter() {
727
+ if (!this.rivTooltip)
728
+ return;
729
+ if (this.tooltipRef) {
730
+ this.cancelClose();
731
+ }
732
+ else {
733
+ const tooltip = this.applicationRef.components[0].injector
734
+ .get(ViewContainerRef)
735
+ .createComponent(TooltipComponent);
736
+ tooltip.instance.anchor = this.el.nativeElement;
737
+ tooltip.instance.content = this.rivTooltip;
738
+ tooltip.instance.theme = this.rivTooltipTheme;
739
+ tooltip.instance.onMouseEnter.subscribe(this.cancelClose.bind(this));
740
+ tooltip.instance.onMouseLeave.subscribe(this.initiateClose.bind(this));
741
+ this.tooltipRef = tooltip;
742
+ }
743
+ }
744
+ onMouseLeave() {
745
+ this.initiateClose();
746
+ }
747
+ initiateClose() {
748
+ this.closeTimeout = window.setTimeout(() => {
749
+ var _a;
750
+ (_a = this.tooltipRef) === null || _a === void 0 ? void 0 : _a.destroy();
751
+ this.tooltipRef = undefined;
752
+ }, this.closeDelay);
753
+ }
754
+ cancelClose() {
755
+ window.clearTimeout(this.closeTimeout);
756
+ }
757
+ }
758
+ TooltipDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: TooltipDirective, deps: [{ token: i0.ElementRef }, { token: i0.ApplicationRef }], target: i0.ɵɵFactoryTarget.Directive });
759
+ TooltipDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.3.0", type: TooltipDirective, selector: "[rivTooltip]", inputs: { rivTooltip: "rivTooltip", rivTooltipTheme: "rivTooltipTheme", closeDelay: "closeDelay" }, host: { listeners: { "mouseenter": "onMouseEnter()", "mouseleave": "onMouseLeave()" } }, ngImport: i0 });
760
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: TooltipDirective, decorators: [{
761
+ type: Directive,
762
+ args: [{
763
+ selector: '[rivTooltip]',
764
+ }]
765
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.ApplicationRef }]; }, propDecorators: { rivTooltip: [{
766
+ type: Input
767
+ }], rivTooltipTheme: [{
768
+ type: Input
769
+ }], closeDelay: [{
770
+ type: Input
771
+ }], onMouseEnter: [{
772
+ type: HostListener,
773
+ args: ['mouseenter']
774
+ }], onMouseLeave: [{
775
+ type: HostListener,
776
+ args: ['mouseleave']
777
+ }] } });
778
+
779
+ class DataTableRowComponent {
780
+ constructor() {
781
+ this.subRow = false;
782
+ }
783
+ }
784
+ DataTableRowComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: DataTableRowComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
785
+ DataTableRowComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: DataTableRowComponent, selector: "[riv-data-table-row]", inputs: { subRow: "subRow" }, host: { properties: { "class.sub-row": "this.subRow" } }, ngImport: i0, template: '<ng-content></ng-content>', isInline: true, styles: [":host:not(.sub-row){border-top:var(--border-width) solid var(--border-light)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
786
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: DataTableRowComponent, decorators: [{
787
+ type: Component,
788
+ args: [{ changeDetection: ChangeDetectionStrategy.OnPush, selector: '[riv-data-table-row]', template: '<ng-content></ng-content>', styles: [":host:not(.sub-row){border-top:var(--border-width) solid var(--border-light)}\n"] }]
789
+ }], propDecorators: { subRow: [{
790
+ type: Input
791
+ }, {
792
+ type: HostBinding,
793
+ args: ['class.sub-row']
794
+ }] } });
795
+
796
+ class DataTableCellComponent {
797
+ constructor(row) {
798
+ this.row = row;
799
+ this.subCell = false;
800
+ }
801
+ ngOnInit() {
802
+ this.subCell = this.row.subRow;
803
+ }
804
+ }
805
+ DataTableCellComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: DataTableCellComponent, deps: [{ token: DataTableRowComponent }], target: i0.ɵɵFactoryTarget.Component });
806
+ DataTableCellComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: DataTableCellComponent, selector: "[riv-data-table-cell]", host: { properties: { "class.sub-cell": "this.subCell" } }, ngImport: i0, template: '<ng-content></ng-content>', isInline: true, styles: [":host{padding:var(--size-large) 0;text-align:right}:host.sub-cell{padding-top:0;padding-left:var(--size-xlarge)}:host:first-child{position:sticky;left:0;z-index:1;background-color:var(--surface-light-0);text-align:left}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
807
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: DataTableCellComponent, decorators: [{
808
+ type: Component,
809
+ args: [{ changeDetection: ChangeDetectionStrategy.OnPush, selector: '[riv-data-table-cell]', template: '<ng-content></ng-content>', styles: [":host{padding:var(--size-large) 0;text-align:right}:host.sub-cell{padding-top:0;padding-left:var(--size-xlarge)}:host:first-child{position:sticky;left:0;z-index:1;background-color:var(--surface-light-0);text-align:left}\n"] }]
810
+ }], ctorParameters: function () { return [{ type: DataTableRowComponent }]; }, propDecorators: { subCell: [{
811
+ type: HostBinding,
812
+ args: ['class.sub-cell']
813
+ }] } });
814
+
815
+ class DataTableComponent {
816
+ }
817
+ DataTableComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: DataTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
818
+ DataTableComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: DataTableComponent, selector: "riv-data-table", ngImport: i0, template: '<table><ng-content></ng-content></table>', isInline: true, styles: [":host{display:block;overflow-x:auto}table{table-layout:fixed;min-width:100%;border-collapse:collapse}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
819
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: DataTableComponent, decorators: [{
820
+ type: Component,
821
+ args: [{ selector: 'riv-data-table', template: '<table><ng-content></ng-content></table>', changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block;overflow-x:auto}table{table-layout:fixed;min-width:100%;border-collapse:collapse}\n"] }]
822
+ }] });
823
+
824
+ class DataTableHeaderCellComponent {
825
+ }
826
+ DataTableHeaderCellComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: DataTableHeaderCellComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
827
+ DataTableHeaderCellComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: DataTableHeaderCellComponent, selector: "[riv-data-table-header-cell]", ngImport: i0, template: '<ng-content></ng-content>', isInline: true, styles: [":host{padding:var(--size-large) 0;font-weight:var(--font-weight-heavy);text-align:right}:host:first-child{position:sticky;left:0;z-index:1;background-color:var(--surface-light-0);text-align:left}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
828
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: DataTableHeaderCellComponent, decorators: [{
829
+ type: Component,
830
+ args: [{ changeDetection: ChangeDetectionStrategy.OnPush, selector: '[riv-data-table-header-cell]', template: '<ng-content></ng-content>', styles: [":host{padding:var(--size-large) 0;font-weight:var(--font-weight-heavy);text-align:right}:host:first-child{position:sticky;left:0;z-index:1;background-color:var(--surface-light-0);text-align:left}\n"] }]
831
+ }] });
832
+
597
833
  class ZeroStateComponent {
598
834
  constructor() {
599
835
  this.message = 'No data to display.';
@@ -636,16 +872,18 @@ class DonutComponent {
636
872
  }
637
873
  }
638
874
  DonutComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: DonutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
639
- DonutComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: DonutComponent, selector: "riv-donut", inputs: { displayLabel: "displayLabel", displayValue: "displayValue", data: "data" }, ngImport: i0, template: "<div *ngIf=\"!empty; else zeroState\" class=\"container\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"100%\"\n [attr.height]=\"HEIGHT\"\n viewBox=\"-128 -128 256 256\"\n >\n <path\n *ngFor=\"let path of arcPaths; let i = index\"\n [attr.d]=\"path\"\n [attr.fill]=\"getFillStyle(i)\"\n ></path>\n </svg>\n <div class=\"display\">\n <div class=\"value\">{{ displayValue }}</div>\n <div class=\"label\">{{ displayLabel }}</div>\n </div>\n</div>\n\n<ng-template #zeroState>\n <riv-zero-state></riv-zero-state>\n</ng-template>\n", styles: [".container{display:grid;grid-template-rows:1fr;grid-template-columns:1fr;justify-items:center;align-items:center}svg{grid-row:1 / 1;grid-column:1 / 1}.display{grid-row:1 / 1;grid-column:1 / 1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--size-small)}.value{font-size:var(--type-6-font-size);line-height:var(--type-6-line-height-0);font-weight:var(--font-weight-heavy)}.label{font-size:var(--type-1-font-size);line-height:var(--type-1-line-height-0);color:var(--type-light-low-contrast)}.value,.label{text-shadow:0 0 var(--size-small) var(--surface-light-0),0 0 var(--size-xsmall) var(--surface-light-0)}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ZeroStateComponent, selector: "riv-zero-state", inputs: ["message"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
875
+ DonutComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: DonutComponent, selector: "riv-donut", inputs: { displayLabel: "displayLabel", displayValue: "displayValue", data: "data", displayTooltip: "displayTooltip" }, ngImport: i0, template: "<div *ngIf=\"!empty; else zeroState\" class=\"container\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"100%\"\n [attr.height]=\"HEIGHT\"\n viewBox=\"-128 -128 256 256\"\n >\n <path\n *ngFor=\"let path of arcPaths; let i = index\"\n [attr.d]=\"path\"\n [attr.fill]=\"getFillStyle(i)\"\n ></path>\n </svg>\n <div class=\"display\">\n <div class=\"value\" [rivTooltip]=\"displayTooltip\">{{ displayValue }}</div>\n <div class=\"label\">{{ displayLabel }}</div>\n </div>\n</div>\n\n<ng-template #zeroState>\n <riv-zero-state></riv-zero-state>\n</ng-template>\n", styles: [".container{display:grid;grid-template-rows:1fr;grid-template-columns:1fr;justify-items:center;align-items:center}svg{grid-row:1 / 1;grid-column:1 / 1}.display{grid-row:1 / 1;grid-column:1 / 1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--size-small)}.value{font-size:var(--type-6-font-size);line-height:var(--type-6-line-height-0);font-weight:var(--font-weight-heavy)}.label{font-size:var(--type-1-font-size);line-height:var(--type-1-line-height-0);color:var(--type-light-low-contrast)}.value,.label{text-shadow:0 0 var(--size-small) var(--surface-light-0),0 0 var(--size-xsmall) var(--surface-light-0)}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: TooltipDirective, selector: "[rivTooltip]", inputs: ["rivTooltip", "rivTooltipTheme", "closeDelay"] }, { kind: "component", type: ZeroStateComponent, selector: "riv-zero-state", inputs: ["message"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
640
876
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: DonutComponent, decorators: [{
641
877
  type: Component,
642
- args: [{ selector: 'riv-donut', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div *ngIf=\"!empty; else zeroState\" class=\"container\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"100%\"\n [attr.height]=\"HEIGHT\"\n viewBox=\"-128 -128 256 256\"\n >\n <path\n *ngFor=\"let path of arcPaths; let i = index\"\n [attr.d]=\"path\"\n [attr.fill]=\"getFillStyle(i)\"\n ></path>\n </svg>\n <div class=\"display\">\n <div class=\"value\">{{ displayValue }}</div>\n <div class=\"label\">{{ displayLabel }}</div>\n </div>\n</div>\n\n<ng-template #zeroState>\n <riv-zero-state></riv-zero-state>\n</ng-template>\n", styles: [".container{display:grid;grid-template-rows:1fr;grid-template-columns:1fr;justify-items:center;align-items:center}svg{grid-row:1 / 1;grid-column:1 / 1}.display{grid-row:1 / 1;grid-column:1 / 1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--size-small)}.value{font-size:var(--type-6-font-size);line-height:var(--type-6-line-height-0);font-weight:var(--font-weight-heavy)}.label{font-size:var(--type-1-font-size);line-height:var(--type-1-line-height-0);color:var(--type-light-low-contrast)}.value,.label{text-shadow:0 0 var(--size-small) var(--surface-light-0),0 0 var(--size-xsmall) var(--surface-light-0)}\n"] }]
878
+ args: [{ selector: 'riv-donut', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div *ngIf=\"!empty; else zeroState\" class=\"container\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"100%\"\n [attr.height]=\"HEIGHT\"\n viewBox=\"-128 -128 256 256\"\n >\n <path\n *ngFor=\"let path of arcPaths; let i = index\"\n [attr.d]=\"path\"\n [attr.fill]=\"getFillStyle(i)\"\n ></path>\n </svg>\n <div class=\"display\">\n <div class=\"value\" [rivTooltip]=\"displayTooltip\">{{ displayValue }}</div>\n <div class=\"label\">{{ displayLabel }}</div>\n </div>\n</div>\n\n<ng-template #zeroState>\n <riv-zero-state></riv-zero-state>\n</ng-template>\n", styles: [".container{display:grid;grid-template-rows:1fr;grid-template-columns:1fr;justify-items:center;align-items:center}svg{grid-row:1 / 1;grid-column:1 / 1}.display{grid-row:1 / 1;grid-column:1 / 1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--size-small)}.value{font-size:var(--type-6-font-size);line-height:var(--type-6-line-height-0);font-weight:var(--font-weight-heavy)}.label{font-size:var(--type-1-font-size);line-height:var(--type-1-line-height-0);color:var(--type-light-low-contrast)}.value,.label{text-shadow:0 0 var(--size-small) var(--surface-light-0),0 0 var(--size-xsmall) var(--surface-light-0)}\n"] }]
643
879
  }], propDecorators: { displayLabel: [{
644
880
  type: Input
645
881
  }], displayValue: [{
646
882
  type: Input
647
883
  }], data: [{
648
884
  type: Input
885
+ }], displayTooltip: [{
886
+ type: Input
649
887
  }] } });
650
888
 
651
889
  class LegendItemComponent {
@@ -661,10 +899,10 @@ class LegendItemComponent {
661
899
  }
662
900
  }
663
901
  LegendItemComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: LegendItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
664
- LegendItemComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: LegendItemComponent, selector: "riv-legend-item", inputs: { label: "label", colorToken: "colorToken", style: "style", visibility: "visibility" }, outputs: { itemClick: "itemClick" }, ngImport: i0, template: "<button (click)=\"itemClick.emit()\">\n <i\n *ngIf=\"visibility === 'visible'\"\n [class.striped]=\"style === 'striped'\"\n [style.background-color]=\"backgroundColor\"\n ></i>\n <riv-icon\n *ngIf=\"visibility === 'hidden'\"\n name=\"EyeOff\"\n [size]=\"16\"\n ></riv-icon>\n <riv-icon *ngIf=\"visibility === 'locked'\" name=\"Lock\" [size]=\"16\"></riv-icon>\n</button>\n<span [class.low-contrast]=\"visibility === 'hidden' || visibility === 'locked'\">\n {{ label }}\n</span>\n", styles: [":host{display:inline-flex;align-items:center;gap:var(--size-small)}i{width:var(--size-large);height:var(--size-large)}i.striped{background-image:repeating-linear-gradient(315deg,transparent 0px,transparent 2.5px,var(--white-100) 2.5px,var(--white-100) 3.5px,transparent 3.5px,transparent 6px)}span{color:var(--type-light-low-contrast);font-size:var(--type-1-font-size);line-height:var(--type-1-line-height-0)}button{display:inline-flex}riv-icon,span.low-contrast{color:var(--type-light-disabled)}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: IconComponent, selector: "riv-icon", inputs: ["name", "size", "customSize", "strokeWidth"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
902
+ LegendItemComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: LegendItemComponent, selector: "riv-legend-item", inputs: { label: "label", colorToken: "colorToken", style: "style", visibility: "visibility", iconTooltip: "iconTooltip" }, outputs: { itemClick: "itemClick" }, ngImport: i0, template: "<button (click)=\"itemClick.emit()\" [rivTooltip]=\"iconTooltip\">\n <i\n *ngIf=\"visibility === 'visible'\"\n [class.striped]=\"style === 'striped'\"\n [style.background-color]=\"backgroundColor\"\n ></i>\n <riv-icon\n *ngIf=\"visibility === 'hidden'\"\n name=\"EyeOff\"\n [size]=\"16\"\n ></riv-icon>\n <riv-icon *ngIf=\"visibility === 'locked'\" name=\"Lock\" [size]=\"16\"></riv-icon>\n</button>\n<span [class.low-contrast]=\"visibility === 'hidden' || visibility === 'locked'\">\n {{ label }}\n</span>\n", styles: [":host{display:inline-flex;align-items:center;gap:var(--size-small)}i{width:var(--size-large);height:var(--size-large)}i.striped{background-image:repeating-linear-gradient(315deg,transparent 0px,transparent 2.5px,var(--white-100) 2.5px,var(--white-100) 3.5px,transparent 3.5px,transparent 6px)}span{color:var(--type-light-low-contrast);font-size:var(--type-1-font-size);line-height:var(--type-1-line-height-0)}button{display:inline-flex}riv-icon,span.low-contrast{color:var(--type-light-disabled)}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: IconComponent, selector: "riv-icon", inputs: ["name", "size", "customSize", "strokeWidth"] }, { kind: "directive", type: TooltipDirective, selector: "[rivTooltip]", inputs: ["rivTooltip", "rivTooltipTheme", "closeDelay"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
665
903
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: LegendItemComponent, decorators: [{
666
904
  type: Component,
667
- args: [{ selector: 'riv-legend-item', changeDetection: ChangeDetectionStrategy.OnPush, template: "<button (click)=\"itemClick.emit()\">\n <i\n *ngIf=\"visibility === 'visible'\"\n [class.striped]=\"style === 'striped'\"\n [style.background-color]=\"backgroundColor\"\n ></i>\n <riv-icon\n *ngIf=\"visibility === 'hidden'\"\n name=\"EyeOff\"\n [size]=\"16\"\n ></riv-icon>\n <riv-icon *ngIf=\"visibility === 'locked'\" name=\"Lock\" [size]=\"16\"></riv-icon>\n</button>\n<span [class.low-contrast]=\"visibility === 'hidden' || visibility === 'locked'\">\n {{ label }}\n</span>\n", styles: [":host{display:inline-flex;align-items:center;gap:var(--size-small)}i{width:var(--size-large);height:var(--size-large)}i.striped{background-image:repeating-linear-gradient(315deg,transparent 0px,transparent 2.5px,var(--white-100) 2.5px,var(--white-100) 3.5px,transparent 3.5px,transparent 6px)}span{color:var(--type-light-low-contrast);font-size:var(--type-1-font-size);line-height:var(--type-1-line-height-0)}button{display:inline-flex}riv-icon,span.low-contrast{color:var(--type-light-disabled)}\n"] }]
905
+ args: [{ selector: 'riv-legend-item', changeDetection: ChangeDetectionStrategy.OnPush, template: "<button (click)=\"itemClick.emit()\" [rivTooltip]=\"iconTooltip\">\n <i\n *ngIf=\"visibility === 'visible'\"\n [class.striped]=\"style === 'striped'\"\n [style.background-color]=\"backgroundColor\"\n ></i>\n <riv-icon\n *ngIf=\"visibility === 'hidden'\"\n name=\"EyeOff\"\n [size]=\"16\"\n ></riv-icon>\n <riv-icon *ngIf=\"visibility === 'locked'\" name=\"Lock\" [size]=\"16\"></riv-icon>\n</button>\n<span [class.low-contrast]=\"visibility === 'hidden' || visibility === 'locked'\">\n {{ label }}\n</span>\n", styles: [":host{display:inline-flex;align-items:center;gap:var(--size-small)}i{width:var(--size-large);height:var(--size-large)}i.striped{background-image:repeating-linear-gradient(315deg,transparent 0px,transparent 2.5px,var(--white-100) 2.5px,var(--white-100) 3.5px,transparent 3.5px,transparent 6px)}span{color:var(--type-light-low-contrast);font-size:var(--type-1-font-size);line-height:var(--type-1-line-height-0)}button{display:inline-flex}riv-icon,span.low-contrast{color:var(--type-light-disabled)}\n"] }]
668
906
  }], propDecorators: { label: [{
669
907
  type: Input
670
908
  }], colorToken: [{
@@ -673,6 +911,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
673
911
  type: Input
674
912
  }], visibility: [{
675
913
  type: Input
914
+ }], iconTooltip: [{
915
+ type: Input
676
916
  }], itemClick: [{
677
917
  type: Output
678
918
  }] } });
@@ -697,30 +937,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
697
937
  type: Input
698
938
  }] } });
699
939
 
700
- var Interval;
701
- (function (Interval) {
702
- Interval["DAY"] = "day";
703
- Interval["WEEK"] = "week";
704
- Interval["MONTH"] = "month";
705
- Interval["YEAR"] = "year";
706
- })(Interval || (Interval = {}));
707
- function getTimeInterval(interval) {
708
- switch (interval) {
709
- case Interval.DAY:
710
- return timeDay;
711
- case Interval.WEEK:
712
- return timeWeek;
713
- case Interval.MONTH:
714
- return timeMonth;
715
- case Interval.YEAR:
716
- return timeYear;
717
- }
718
- }
719
- function getDateRange$1(configs) {
940
+ function getDateRange$1(stacks) {
720
941
  let min = Infinity;
721
942
  let max = -Infinity;
722
- for (const config of configs) {
723
- for (const series of config.series) {
943
+ for (const stack of stacks) {
944
+ for (const series of stack) {
724
945
  for (const { date } of series.data) {
725
946
  const value = date.valueOf();
726
947
  min = Math.min(min, value);
@@ -730,323 +951,22 @@ function getDateRange$1(configs) {
730
951
  }
731
952
  return [new Date(min), new Date(max)];
732
953
  }
733
- function getMinorIntervalFormat(interval) {
734
- switch (interval) {
735
- case Interval.DAY:
736
- case Interval.WEEK:
737
- return '%-d';
738
- case Interval.MONTH:
739
- return '%b';
740
- case Interval.YEAR:
741
- return '%Y';
742
- }
743
- }
744
- function getMajorInterval(interval) {
745
- switch (interval) {
746
- case Interval.DAY:
747
- case Interval.WEEK:
748
- return Interval.MONTH;
749
- default:
750
- return Interval.YEAR;
751
- }
752
- }
753
- function getMajorIntervalFormat(interval) {
754
- switch (interval) {
755
- case Interval.YEAR:
756
- return '%Y';
757
- case Interval.MONTH:
758
- return '%b %Y';
759
- default:
760
- return '%d';
761
- }
762
- }
763
954
  // TODO: once we upgrade to Angular 16, this component can be cleaned up with
764
- // signals instead of RxJS. See commit e238c2d.
765
- class TimeSeriesComponent {
955
+ // signals instead of RxJS.
956
+ class StackedColumnComponent {
766
957
  constructor() {
767
- this.input$ = new BehaviorSubject([
768
- {
769
- pointReducer: points => points.reduce((total, { value }) => total + value, 0),
770
- valueFormatter: v => { var _a; return (_a = new DecimalPipe('en-US').transform(v)) !== null && _a !== void 0 ? _a : ''; },
771
- series: [],
772
- },
773
- ]);
958
+ this.input$ = new BehaviorSubject([]);
774
959
  this.width$ = new BehaviorSubject(960);
775
960
  this.height$ = new BehaviorSubject(256);
776
- this.BOTTOM_OFFSET = 24;
777
- this.LEFT_OFFSET = 48;
778
- this.TOP_PADDING = 16;
779
- this.LEFT_RIGHT_PADDING = 8;
780
- this.BOTTOM_PADDING = 8;
781
- this.Y_TICK_COUNT = 5;
782
- this.X_MINOR_TICK_LIMIT = 15;
783
- this.dateRange$ = this.input$.pipe(map(getDateRange$1), shareReplay({ refCount: true, bufferSize: 1 }));
784
- this.binInterval$ = this.dateRange$.pipe(map(([minDate, maxDate]) => {
785
- const diff = timeDay.count(new Date(minDate), new Date(maxDate));
786
- if (diff >= 365 * 3) {
787
- return Interval.YEAR;
788
- }
789
- else if (diff >= 365) {
790
- return Interval.MONTH;
791
- }
792
- else if (diff >= 90) {
793
- return Interval.WEEK;
794
- }
795
- else {
796
- return Interval.DAY;
797
- }
798
- }), shareReplay({ refCount: true, bufferSize: 1 }));
799
- this.binnedData$ = combineLatest([this.input$, this.binInterval$]).pipe(map(([input, binInterval]) => input.map((config) => {
800
- return Object.assign(Object.assign({}, config), { series: config.series.map(series => {
801
- const binned = new Map();
802
- for (const point of series.data) {
803
- const bin = getTimeInterval(binInterval)
804
- .floor(point.date)
805
- .valueOf();
806
- if (!binned.has(bin)) {
807
- binned.set(bin, []);
808
- }
809
- binned.get(bin).push(point);
810
- }
811
- return Object.assign(Object.assign({}, series), { data: [...binned.entries()].map(([dateValue, points]) => ({
812
- date: new Date(dateValue),
813
- value: config.pointReducer(points),
814
- })) });
815
- }) });
816
- })), shareReplay({ refCount: true, bufferSize: 1 }));
817
- this.binnedDateRange$ = this.binnedData$.pipe(map(getDateRange$1), shareReplay({ refCount: true, bufferSize: 1 }));
961
+ this.valueFormatter = v => v.toString();
818
962
  this.drawData$ = combineLatest([
819
- this.binnedData$,
820
- this.binnedDateRange$,
821
- this.binInterval$,
963
+ this.input$,
822
964
  this.width$,
823
965
  this.height$,
824
- ]).pipe(map(([binnedData, binnedDateRange, binInterval, width, height]) => {
825
- const viewBox = `0 0 ${width} ${height}`;
826
- const xScale = scaleLinear()
827
- .domain(binnedDateRange)
828
- .range([
829
- this.LEFT_OFFSET + this.LEFT_RIGHT_PADDING,
830
- width - this.LEFT_RIGHT_PADDING * 2,
831
- ]);
832
- const xMinorIntervalFormat = getMinorIntervalFormat(binInterval);
833
- const [minDateValue, maxDateValue] = binnedDateRange;
834
- const minorFormatter = timeFormat(xMinorIntervalFormat);
835
- const xMinorTicks = getTimeInterval(binInterval)
836
- .range(minDateValue, timeDay.offset(maxDateValue, 1))
837
- .map(date => ({
838
- value: date.valueOf(),
839
- label: minorFormatter(date),
840
- }))
841
- .filter((_, i, arr) => arr.length > this.X_MINOR_TICK_LIMIT
842
- ? i % Math.round(arr.length / this.X_MINOR_TICK_LIMIT) === 0
843
- : true);
844
- const xMajorInterval = getMajorInterval(binInterval);
845
- const xMajorIntervalFormat = getMajorIntervalFormat(xMajorInterval);
846
- const timeInterval = getTimeInterval(xMajorInterval);
847
- const tickFloor = timeInterval.floor(minDateValue);
848
- const tickCeiling = timeInterval.ceil(timeDay.offset(maxDateValue, 1));
849
- const majorFormatter = timeFormat(xMajorIntervalFormat);
850
- const xMajorTicks = timeInterval
851
- .range(tickFloor, tickCeiling)
852
- .map(tickDate => ({
853
- label: xMajorInterval === binInterval ? '' : majorFormatter(tickDate),
854
- value: tickDate.valueOf(),
855
- }));
856
- const x = { xMax: maxDateValue, xScale, xMinorTicks, xMajorTicks };
857
- const [y1, y2] = binnedData.map(config => {
858
- var _a, _b;
859
- const flattenedValues = config.series.reduce((values, series) => [
860
- ...values,
861
- ...series.data.map(({ value }) => value),
862
- ], []);
863
- const yMax = (_a = config.max) !== null && _a !== void 0 ? _a : Math.max(...flattenedValues);
864
- const yMin = (_b = config.min) !== null && _b !== void 0 ? _b : Math.min(...flattenedValues, 0);
865
- const yScale = scaleLinear()
866
- .domain([yMin, yMax])
867
- .range([
868
- height -
869
- this.BOTTOM_OFFSET -
870
- (this.BOTTOM_PADDING + this.TOP_PADDING),
871
- this.TOP_PADDING,
872
- ]);
873
- const yTicks = yScale.ticks(this.Y_TICK_COUNT);
874
- const series = config.series.map(series => (Object.assign(Object.assign({}, series), { path: line()
875
- .x(d => xScale(d.date))
876
- .y(d => yScale(d.value))(series.data), stroke: `var(${series.colorToken})`, markers: series.data.map(point => (Object.assign(Object.assign({}, point), { x: xScale(point.date), y: yScale(point.value) }))) })));
877
- return Object.assign(Object.assign({}, config), { series,
878
- yMax,
879
- yMin,
880
- yScale,
881
- yTicks });
882
- });
883
- // If we have a y2, coerce y1's ticks to be visually equivalent to y2's ticks.
884
- if (y2 === null || y2 === void 0 ? void 0 : y2.yTicks) {
885
- const tickConversionScale = scaleLinear()
886
- .range(y1.yScale.domain())
887
- .domain(y2.yScale.domain());
888
- y1.yTicks = y2.yTicks.map(tickConversionScale);
889
- }
890
- return { viewBox, x, y1, y2 };
891
- }), shareReplay({ refCount: true, bufferSize: 1 }));
892
- this.legend$ = this.binnedData$.pipe(map(binnedData => binnedData.reduce((items, config) => [
893
- ...items,
894
- ...config.series.map(series => ({
895
- label: series.label,
896
- colorToken: series.colorToken,
897
- })),
898
- ], [])));
899
- this.empty$ = this.binnedData$.pipe(map(binnedData => binnedData.every(config => config.series.every(series => series.data.length === 0))), shareReplay({ refCount: true, bufferSize: 1 }));
900
- this.hoveredMarker$ = new BehaviorSubject(null);
901
- this.callout$ = combineLatest([this.hoveredMarker$, this.drawData$]).pipe(map(([hoveredMarker, drawData]) => {
902
- if (!hoveredMarker)
903
- return null;
904
- const { target } = hoveredMarker.event;
905
- if (!target)
906
- return null;
907
- const markerRect = target.getBoundingClientRect();
908
- const padding = 8;
909
- const anchor = new DOMRect(markerRect.left - padding, markerRect.top - padding, markerRect.width + padding * 2, markerRect.height + padding * 2);
910
- const metrics = [];
911
- for (const series of drawData.y1.series) {
912
- const match = series.markers.find(marker => marker.x === hoveredMarker.marker.x);
913
- if (match) {
914
- metrics.push({
915
- label: series.label,
916
- value: drawData.y1.valueFormatter(match.value),
917
- });
918
- }
919
- }
920
- if (drawData.y2) {
921
- for (const series of drawData.y2.series) {
922
- const match = series.markers.find(marker => marker.x === hoveredMarker.marker.x);
923
- if (match) {
924
- metrics.push({
925
- label: series.label,
926
- value: drawData.y2.valueFormatter(match.value),
927
- });
928
- }
929
- }
930
- }
931
- return { anchor, metrics };
932
- }));
933
- }
934
- set input(v) {
935
- this.input$.next(v);
936
- }
937
- get input() {
938
- return this.input$.getValue();
939
- }
940
- set width(v) {
941
- this.width$.next(v);
942
- }
943
- get width() {
944
- return this.width$.getValue();
945
- }
946
- set height(v) {
947
- this.height$.next(v);
948
- }
949
- get height() {
950
- return this.height$.getValue();
951
- }
952
- }
953
- TimeSeriesComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: TimeSeriesComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
954
- TimeSeriesComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: TimeSeriesComponent, selector: "riv-time-series", inputs: { input: "input", width: "width", height: "height" }, ngImport: i0, template: "<div *ngIf=\"!(empty$ | async); else zeroState\" class=\"container\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n *ngIf=\"drawData$ | async; let d\"\n [attr.viewBox]=\"d.viewBox\"\n >\n <g *ngFor=\"let tick of d.x.xMajorTicks\">\n <rect\n class=\"tick\"\n [attr.x]=\"d.x.xScale(tick.value)\"\n y=\"0\"\n width=\"1\"\n [attr.height]=\"d.y1.yScale(d.y1.yMin)\"\n ></rect>\n <text\n class=\"x-major-tick-label\"\n [attr.x]=\"d.x.xScale(tick.value)\"\n [attr.y]=\"d.y1.yScale(d.y1.yMin)\"\n dx=\"4\"\n dy=\"-4\"\n >\n {{ tick.label }}\n </text>\n </g>\n <g *ngFor=\"let tick of d.x.xMinorTicks\">\n <text\n class=\"x-minor-tick-label\"\n [attr.x]=\"d.x.xScale(tick.value)\"\n [attr.y]=\"d.y1.yScale(d.y1.yMin)\"\n text-anchor=\"middle\"\n dominant-baseline=\"hanging\"\n dy=\"8\"\n >\n {{ tick.label }}\n <title>{{ tick.value | date }}</title>\n </text>\n </g>\n <g *ngFor=\"let tick of d.y1.yTicks\">\n <rect\n class=\"tick\"\n x=\"0\"\n [attr.y]=\"d.y1.yScale(tick)\"\n width=\"100%\"\n height=\"1\"\n ></rect>\n <text class=\"y-tick-label\" x=\"0\" [attr.y]=\"d.y1.yScale(tick)\" dy=\"-4\">\n {{ d.y1.valueFormatter(tick) }}\n </text>\n </g>\n\n <g *ngFor=\"let tick of d.y2?.yTicks\">\n <text\n class=\"y-tick-label\"\n [attr.x]=\"d.x.xScale(d.x.xMax)\"\n [attr.y]=\"d.y2?.yScale(tick)\"\n text-anchor=\"end\"\n dy=\"-4\"\n >\n {{ d.y2?.valueFormatter(tick) }}\n </text>\n </g>\n\n <g *ngIf=\"hoveredMarker$ | async; let hoveredMarker\">\n <line\n class=\"hover-rule\"\n [attr.x1]=\"hoveredMarker.marker.x\"\n [attr.y1]=\"d.y1.yScale(d.y1.yMin)\"\n [attr.x2]=\"hoveredMarker.marker.x\"\n [attr.y2]=\"d.y1.yScale(d.y1.yMax)\"\n stroke-width=\"2\"\n stroke-dasharray=\"4\"\n />\n </g>\n\n <ng-template #seriesTpl let-series=\"series\">\n <path\n class=\"data path\"\n [class.marker-hovered]=\"!!(hoveredMarker$ | async)\"\n [attr.d]=\"series.path\"\n fill=\"none\"\n stroke-width=\"2\"\n [attr.stroke]=\"series.stroke\"\n [attr.stroke-dasharray]=\"series.style === 'dashed' ? '4' : null\"\n ></path>\n <circle\n *ngFor=\"let marker of series.markers\"\n class=\"data marker\"\n [class.focused]=\"(hoveredMarker$ | async)?.marker?.x === marker.x\"\n [class.blurred]=\"\n (hoveredMarker$ | async) !== null &&\n (hoveredMarker$ | async)?.marker?.x !== marker.x\n \"\n [attr.cx]=\"marker.x\"\n [attr.cy]=\"marker.y\"\n r=\"3.5\"\n stroke-width=\"2\"\n [attr.stroke]=\"series.stroke\"\n (mouseover)=\"hoveredMarker$.next({ event: $event, marker: marker })\"\n (mouseleave)=\"hoveredMarker$.next(null)\"\n ></circle>\n </ng-template>\n <g *ngFor=\"let series of d.y1.series\">\n <ng-container\n *ngTemplateOutlet=\"seriesTpl; context: { series: series }\"\n ></ng-container>\n </g>\n <g *ngFor=\"let series of d.y2?.series\">\n <ng-container\n *ngTemplateOutlet=\"seriesTpl; context: { series: series }\"\n ></ng-container>\n </g>\n </svg>\n <legend>\n <riv-legend-item\n *ngFor=\"let item of legend$ | async\"\n [label]=\"item.label\"\n [colorToken]=\"item.colorToken\"\n ></riv-legend-item>\n </legend>\n</div>\n\n<ng-container *ngIf=\"callout$ | async; let callout\">\n <riv-callout\n *riv-callout\n [anchor]=\"callout.anchor\"\n [isModal]=\"false\"\n [preferredPosition]=\"'top-center'\"\n >\n <div class=\"callout-content\">\n <div class=\"callout-metric\" *ngFor=\"let metric of callout.metrics\">\n <div>{{ metric.label }}</div>\n <div class=\"callout-metric-value\">{{ metric.value }}</div>\n </div>\n </div>\n </riv-callout>\n</ng-container>\n\n<ng-template #zeroState>\n <riv-zero-state></riv-zero-state>\n</ng-template>\n", styles: [".container{display:flex;flex-direction:column;gap:var(--size-xlarge)}.y-tick-label,.x-major-tick-label{font-size:var(--type-0-font-size);line-height:var(--type-0-line-height-0);fill:var(--type-light-low-contrast)}.x-minor-tick-label{font-size:var(--type-1-font-size);line-height:var(--type-1-line-height-0);fill:var(--type-light-low-contrast);text-anchor:middle}.tick{fill:var(--gray-20)}.data.path{transition:stroke-opacity var(--short-transition)}.data.path.marker-hovered{stroke-opacity:.4}.data.marker{fill:var(--surface-light-0);transition:stroke-opacity var(--short-transition)}.data.marker.focused{stroke-opacity:1;filter:drop-shadow(0 1px 1px rgba(10,2,22,.15))}.data.marker.blurred{stroke-opacity:.4}.hover-rule{stroke:var(--gray-20)}legend{display:flex;flex-wrap:wrap;gap:var(--size-large);justify-content:flex-start;align-items:baseline}.callout-content{padding:var(--size-large);display:flex;gap:var(--size-medium)}.callout-metric{display:flex;flex-direction:column;gap:var(--size-xsmall);font-size:var(--type-1-font-size);line-height:var(--type-1-line-height-0)}.callout-metric-value{font-weight:var(--font-weight-heavy)}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: CalloutComponent, selector: "riv-callout", inputs: ["anchor", "isModal", "preferredPosition", "allowedPositions", "fallbackDirection", "showCaret", "theme"], outputs: ["close"] }, { kind: "directive", type: CalloutDirective, selector: "[riv-callout]" }, { kind: "component", type: LegendItemComponent, selector: "riv-legend-item", inputs: ["label", "colorToken", "style", "visibility"], outputs: ["itemClick"] }, { kind: "component", type: ZeroStateComponent, selector: "riv-zero-state", inputs: ["message"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i1.DatePipe, name: "date" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
955
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: TimeSeriesComponent, decorators: [{
956
- type: Component,
957
- args: [{ selector: 'riv-time-series', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div *ngIf=\"!(empty$ | async); else zeroState\" class=\"container\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n *ngIf=\"drawData$ | async; let d\"\n [attr.viewBox]=\"d.viewBox\"\n >\n <g *ngFor=\"let tick of d.x.xMajorTicks\">\n <rect\n class=\"tick\"\n [attr.x]=\"d.x.xScale(tick.value)\"\n y=\"0\"\n width=\"1\"\n [attr.height]=\"d.y1.yScale(d.y1.yMin)\"\n ></rect>\n <text\n class=\"x-major-tick-label\"\n [attr.x]=\"d.x.xScale(tick.value)\"\n [attr.y]=\"d.y1.yScale(d.y1.yMin)\"\n dx=\"4\"\n dy=\"-4\"\n >\n {{ tick.label }}\n </text>\n </g>\n <g *ngFor=\"let tick of d.x.xMinorTicks\">\n <text\n class=\"x-minor-tick-label\"\n [attr.x]=\"d.x.xScale(tick.value)\"\n [attr.y]=\"d.y1.yScale(d.y1.yMin)\"\n text-anchor=\"middle\"\n dominant-baseline=\"hanging\"\n dy=\"8\"\n >\n {{ tick.label }}\n <title>{{ tick.value | date }}</title>\n </text>\n </g>\n <g *ngFor=\"let tick of d.y1.yTicks\">\n <rect\n class=\"tick\"\n x=\"0\"\n [attr.y]=\"d.y1.yScale(tick)\"\n width=\"100%\"\n height=\"1\"\n ></rect>\n <text class=\"y-tick-label\" x=\"0\" [attr.y]=\"d.y1.yScale(tick)\" dy=\"-4\">\n {{ d.y1.valueFormatter(tick) }}\n </text>\n </g>\n\n <g *ngFor=\"let tick of d.y2?.yTicks\">\n <text\n class=\"y-tick-label\"\n [attr.x]=\"d.x.xScale(d.x.xMax)\"\n [attr.y]=\"d.y2?.yScale(tick)\"\n text-anchor=\"end\"\n dy=\"-4\"\n >\n {{ d.y2?.valueFormatter(tick) }}\n </text>\n </g>\n\n <g *ngIf=\"hoveredMarker$ | async; let hoveredMarker\">\n <line\n class=\"hover-rule\"\n [attr.x1]=\"hoveredMarker.marker.x\"\n [attr.y1]=\"d.y1.yScale(d.y1.yMin)\"\n [attr.x2]=\"hoveredMarker.marker.x\"\n [attr.y2]=\"d.y1.yScale(d.y1.yMax)\"\n stroke-width=\"2\"\n stroke-dasharray=\"4\"\n />\n </g>\n\n <ng-template #seriesTpl let-series=\"series\">\n <path\n class=\"data path\"\n [class.marker-hovered]=\"!!(hoveredMarker$ | async)\"\n [attr.d]=\"series.path\"\n fill=\"none\"\n stroke-width=\"2\"\n [attr.stroke]=\"series.stroke\"\n [attr.stroke-dasharray]=\"series.style === 'dashed' ? '4' : null\"\n ></path>\n <circle\n *ngFor=\"let marker of series.markers\"\n class=\"data marker\"\n [class.focused]=\"(hoveredMarker$ | async)?.marker?.x === marker.x\"\n [class.blurred]=\"\n (hoveredMarker$ | async) !== null &&\n (hoveredMarker$ | async)?.marker?.x !== marker.x\n \"\n [attr.cx]=\"marker.x\"\n [attr.cy]=\"marker.y\"\n r=\"3.5\"\n stroke-width=\"2\"\n [attr.stroke]=\"series.stroke\"\n (mouseover)=\"hoveredMarker$.next({ event: $event, marker: marker })\"\n (mouseleave)=\"hoveredMarker$.next(null)\"\n ></circle>\n </ng-template>\n <g *ngFor=\"let series of d.y1.series\">\n <ng-container\n *ngTemplateOutlet=\"seriesTpl; context: { series: series }\"\n ></ng-container>\n </g>\n <g *ngFor=\"let series of d.y2?.series\">\n <ng-container\n *ngTemplateOutlet=\"seriesTpl; context: { series: series }\"\n ></ng-container>\n </g>\n </svg>\n <legend>\n <riv-legend-item\n *ngFor=\"let item of legend$ | async\"\n [label]=\"item.label\"\n [colorToken]=\"item.colorToken\"\n ></riv-legend-item>\n </legend>\n</div>\n\n<ng-container *ngIf=\"callout$ | async; let callout\">\n <riv-callout\n *riv-callout\n [anchor]=\"callout.anchor\"\n [isModal]=\"false\"\n [preferredPosition]=\"'top-center'\"\n >\n <div class=\"callout-content\">\n <div class=\"callout-metric\" *ngFor=\"let metric of callout.metrics\">\n <div>{{ metric.label }}</div>\n <div class=\"callout-metric-value\">{{ metric.value }}</div>\n </div>\n </div>\n </riv-callout>\n</ng-container>\n\n<ng-template #zeroState>\n <riv-zero-state></riv-zero-state>\n</ng-template>\n", styles: [".container{display:flex;flex-direction:column;gap:var(--size-xlarge)}.y-tick-label,.x-major-tick-label{font-size:var(--type-0-font-size);line-height:var(--type-0-line-height-0);fill:var(--type-light-low-contrast)}.x-minor-tick-label{font-size:var(--type-1-font-size);line-height:var(--type-1-line-height-0);fill:var(--type-light-low-contrast);text-anchor:middle}.tick{fill:var(--gray-20)}.data.path{transition:stroke-opacity var(--short-transition)}.data.path.marker-hovered{stroke-opacity:.4}.data.marker{fill:var(--surface-light-0);transition:stroke-opacity var(--short-transition)}.data.marker.focused{stroke-opacity:1;filter:drop-shadow(0 1px 1px rgba(10,2,22,.15))}.data.marker.blurred{stroke-opacity:.4}.hover-rule{stroke:var(--gray-20)}legend{display:flex;flex-wrap:wrap;gap:var(--size-large);justify-content:flex-start;align-items:baseline}.callout-content{padding:var(--size-large);display:flex;gap:var(--size-medium)}.callout-metric{display:flex;flex-direction:column;gap:var(--size-xsmall);font-size:var(--type-1-font-size);line-height:var(--type-1-line-height-0)}.callout-metric-value{font-weight:var(--font-weight-heavy)}\n"] }]
958
- }], propDecorators: { input: [{
959
- type: Input
960
- }], width: [{
961
- type: Input
962
- }], height: [{
963
- type: Input
964
- }] } });
965
-
966
- class DataTableComponent {
967
- }
968
- DataTableComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: DataTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
969
- DataTableComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: DataTableComponent, selector: "riv-data-table", ngImport: i0, template: '<table><ng-content></ng-content></table>', isInline: true, styles: [":host{display:block;overflow-x:auto}table{table-layout:fixed;min-width:100%;border-collapse:collapse}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
970
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: DataTableComponent, decorators: [{
971
- type: Component,
972
- args: [{ selector: 'riv-data-table', template: '<table><ng-content></ng-content></table>', changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block;overflow-x:auto}table{table-layout:fixed;min-width:100%;border-collapse:collapse}\n"] }]
973
- }] });
974
-
975
- class DataTableRowComponent {
976
- constructor() {
977
- this.subRow = false;
978
- }
979
- }
980
- DataTableRowComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: DataTableRowComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
981
- DataTableRowComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: DataTableRowComponent, selector: "[riv-data-table-row]", inputs: { subRow: "subRow" }, host: { properties: { "class.sub-row": "this.subRow" } }, ngImport: i0, template: '<ng-content></ng-content>', isInline: true, styles: [":host:not(.sub-row){border-top:var(--border-width) solid var(--border-light)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
982
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: DataTableRowComponent, decorators: [{
983
- type: Component,
984
- args: [{ changeDetection: ChangeDetectionStrategy.OnPush, selector: '[riv-data-table-row]', template: '<ng-content></ng-content>', styles: [":host:not(.sub-row){border-top:var(--border-width) solid var(--border-light)}\n"] }]
985
- }], propDecorators: { subRow: [{
986
- type: Input
987
- }, {
988
- type: HostBinding,
989
- args: ['class.sub-row']
990
- }] } });
991
-
992
- class DataTableCellComponent {
993
- constructor(row) {
994
- this.row = row;
995
- this.subCell = false;
996
- }
997
- ngOnInit() {
998
- this.subCell = this.row.subRow;
999
- }
1000
- }
1001
- DataTableCellComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: DataTableCellComponent, deps: [{ token: DataTableRowComponent }], target: i0.ɵɵFactoryTarget.Component });
1002
- DataTableCellComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: DataTableCellComponent, selector: "[riv-data-table-cell]", host: { properties: { "class.sub-cell": "this.subCell" } }, ngImport: i0, template: '<ng-content></ng-content>', isInline: true, styles: [":host{padding:var(--size-large) 0;text-align:right}:host.sub-cell{padding-top:0;padding-left:var(--size-xlarge)}:host:first-child{position:sticky;left:0;z-index:1;background-color:var(--surface-light-0);text-align:left}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1003
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: DataTableCellComponent, decorators: [{
1004
- type: Component,
1005
- args: [{ changeDetection: ChangeDetectionStrategy.OnPush, selector: '[riv-data-table-cell]', template: '<ng-content></ng-content>', styles: [":host{padding:var(--size-large) 0;text-align:right}:host.sub-cell{padding-top:0;padding-left:var(--size-xlarge)}:host:first-child{position:sticky;left:0;z-index:1;background-color:var(--surface-light-0);text-align:left}\n"] }]
1006
- }], ctorParameters: function () { return [{ type: DataTableRowComponent }]; }, propDecorators: { subCell: [{
1007
- type: HostBinding,
1008
- args: ['class.sub-cell']
1009
- }] } });
1010
-
1011
- class DataTableHeaderCellComponent {
1012
- }
1013
- DataTableHeaderCellComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: DataTableHeaderCellComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1014
- DataTableHeaderCellComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: DataTableHeaderCellComponent, selector: "[riv-data-table-header-cell]", ngImport: i0, template: '<ng-content></ng-content>', isInline: true, styles: [":host{padding:var(--size-large) 0;font-weight:var(--font-weight-heavy);text-align:right}:host:first-child{position:sticky;left:0;z-index:1;background-color:var(--surface-light-0);text-align:left}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1015
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: DataTableHeaderCellComponent, decorators: [{
1016
- type: Component,
1017
- args: [{ changeDetection: ChangeDetectionStrategy.OnPush, selector: '[riv-data-table-header-cell]', template: '<ng-content></ng-content>', styles: [":host{padding:var(--size-large) 0;font-weight:var(--font-weight-heavy);text-align:right}:host:first-child{position:sticky;left:0;z-index:1;background-color:var(--surface-light-0);text-align:left}\n"] }]
1018
- }] });
1019
-
1020
- function getDateRange(stacks) {
1021
- let min = Infinity;
1022
- let max = -Infinity;
1023
- for (const stack of stacks) {
1024
- for (const series of stack) {
1025
- for (const { date } of series.data) {
1026
- const value = date.valueOf();
1027
- min = Math.min(min, value);
1028
- max = Math.max(max, value);
1029
- }
1030
- }
1031
- }
1032
- return [new Date(min), new Date(max)];
1033
- }
1034
- // TODO: once we upgrade to Angular 16, this component can be cleaned up with
1035
- // signals instead of RxJS.
1036
- class StackedColumnComponent {
1037
- constructor() {
1038
- this.input$ = new BehaviorSubject([]);
1039
- this.width$ = new BehaviorSubject(960);
1040
- this.height$ = new BehaviorSubject(256);
1041
- this.valueFormatter = v => v.toString();
1042
- this.drawData$ = combineLatest([
1043
- this.input$,
1044
- this.width$,
1045
- this.height$,
1046
- ]).pipe(map(([input, width, height]) => {
966
+ ]).pipe(map(([input, width, height]) => {
1047
967
  const viewBox = `0 0 ${width} ${height}`;
1048
968
  const padding = 8;
1049
- const [minDate, maxDate] = getDateRange(input);
969
+ const [minDate, maxDate] = getDateRange$1(input);
1050
970
  const xSteps = timeMonth.range(timeMonth.floor(minDate), timeMonth.floor(timeMonth.offset(maxDate, 1)));
1051
971
  const xFormatter = timeFormat('%b');
1052
972
  const xOuterScale = scaleBand()
@@ -1192,6 +1112,272 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
1192
1112
  type: Input
1193
1113
  }] } });
1194
1114
 
1115
+ var Interval;
1116
+ (function (Interval) {
1117
+ Interval["DAY"] = "day";
1118
+ Interval["WEEK"] = "week";
1119
+ Interval["MONTH"] = "month";
1120
+ Interval["YEAR"] = "year";
1121
+ })(Interval || (Interval = {}));
1122
+ function getTimeInterval(interval) {
1123
+ switch (interval) {
1124
+ case Interval.DAY:
1125
+ return timeDay;
1126
+ case Interval.WEEK:
1127
+ return timeWeek;
1128
+ case Interval.MONTH:
1129
+ return timeMonth;
1130
+ case Interval.YEAR:
1131
+ return timeYear;
1132
+ }
1133
+ }
1134
+ function getDateRange(configs) {
1135
+ let min = Infinity;
1136
+ let max = -Infinity;
1137
+ for (const config of configs) {
1138
+ for (const series of config.series) {
1139
+ for (const { date } of series.data) {
1140
+ const value = date.valueOf();
1141
+ min = Math.min(min, value);
1142
+ max = Math.max(max, value);
1143
+ }
1144
+ }
1145
+ }
1146
+ return [new Date(min), new Date(max)];
1147
+ }
1148
+ function getMinorIntervalFormat(interval) {
1149
+ switch (interval) {
1150
+ case Interval.DAY:
1151
+ case Interval.WEEK:
1152
+ return '%-d';
1153
+ case Interval.MONTH:
1154
+ return '%b';
1155
+ case Interval.YEAR:
1156
+ return '%Y';
1157
+ }
1158
+ }
1159
+ function getMajorInterval(interval) {
1160
+ switch (interval) {
1161
+ case Interval.DAY:
1162
+ case Interval.WEEK:
1163
+ return Interval.MONTH;
1164
+ default:
1165
+ return Interval.YEAR;
1166
+ }
1167
+ }
1168
+ function getMajorIntervalFormat(interval) {
1169
+ switch (interval) {
1170
+ case Interval.YEAR:
1171
+ return '%Y';
1172
+ case Interval.MONTH:
1173
+ return '%b %Y';
1174
+ default:
1175
+ return '%d';
1176
+ }
1177
+ }
1178
+ // TODO: once we upgrade to Angular 16, this component can be cleaned up with
1179
+ // signals instead of RxJS. See commit e238c2d.
1180
+ class TimeSeriesComponent {
1181
+ constructor() {
1182
+ this.input$ = new BehaviorSubject([
1183
+ {
1184
+ pointReducer: points => points.reduce((total, { value }) => total + value, 0),
1185
+ valueFormatter: v => { var _a; return (_a = new DecimalPipe('en-US').transform(v)) !== null && _a !== void 0 ? _a : ''; },
1186
+ series: [],
1187
+ },
1188
+ ]);
1189
+ this.width$ = new BehaviorSubject(960);
1190
+ this.height$ = new BehaviorSubject(256);
1191
+ this.BOTTOM_OFFSET = 24;
1192
+ this.LEFT_OFFSET = 48;
1193
+ this.TOP_PADDING = 16;
1194
+ this.LEFT_RIGHT_PADDING = 8;
1195
+ this.BOTTOM_PADDING = 8;
1196
+ this.Y_TICK_COUNT = 5;
1197
+ this.X_MINOR_TICK_LIMIT = 15;
1198
+ this.dateRange$ = this.input$.pipe(map(getDateRange), shareReplay({ refCount: true, bufferSize: 1 }));
1199
+ this.binInterval$ = this.dateRange$.pipe(map(([minDate, maxDate]) => {
1200
+ const diff = timeDay.count(new Date(minDate), new Date(maxDate));
1201
+ if (diff >= 365 * 3) {
1202
+ return Interval.YEAR;
1203
+ }
1204
+ else if (diff >= 365) {
1205
+ return Interval.MONTH;
1206
+ }
1207
+ else if (diff >= 90) {
1208
+ return Interval.WEEK;
1209
+ }
1210
+ else {
1211
+ return Interval.DAY;
1212
+ }
1213
+ }), shareReplay({ refCount: true, bufferSize: 1 }));
1214
+ this.binnedData$ = combineLatest([this.input$, this.binInterval$]).pipe(map(([input, binInterval]) => input.map((config) => {
1215
+ return Object.assign(Object.assign({}, config), { series: config.series.map(series => {
1216
+ const binned = new Map();
1217
+ for (const point of series.data) {
1218
+ const bin = getTimeInterval(binInterval)
1219
+ .floor(point.date)
1220
+ .valueOf();
1221
+ if (!binned.has(bin)) {
1222
+ binned.set(bin, []);
1223
+ }
1224
+ binned.get(bin).push(point);
1225
+ }
1226
+ return Object.assign(Object.assign({}, series), { data: [...binned.entries()].map(([dateValue, points]) => ({
1227
+ date: new Date(dateValue),
1228
+ value: config.pointReducer(points),
1229
+ })) });
1230
+ }) });
1231
+ })), shareReplay({ refCount: true, bufferSize: 1 }));
1232
+ this.binnedDateRange$ = this.binnedData$.pipe(map(getDateRange), shareReplay({ refCount: true, bufferSize: 1 }));
1233
+ this.drawData$ = combineLatest([
1234
+ this.binnedData$,
1235
+ this.binnedDateRange$,
1236
+ this.binInterval$,
1237
+ this.width$,
1238
+ this.height$,
1239
+ ]).pipe(map(([binnedData, binnedDateRange, binInterval, width, height]) => {
1240
+ const viewBox = `0 0 ${width} ${height}`;
1241
+ const xScale = scaleLinear()
1242
+ .domain(binnedDateRange)
1243
+ .range([
1244
+ this.LEFT_OFFSET + this.LEFT_RIGHT_PADDING,
1245
+ width - this.LEFT_RIGHT_PADDING * 2,
1246
+ ]);
1247
+ const xMinorIntervalFormat = getMinorIntervalFormat(binInterval);
1248
+ const [minDateValue, maxDateValue] = binnedDateRange;
1249
+ const minorFormatter = timeFormat(xMinorIntervalFormat);
1250
+ const xMinorTicks = getTimeInterval(binInterval)
1251
+ .range(minDateValue, timeDay.offset(maxDateValue, 1))
1252
+ .map(date => ({
1253
+ value: date.valueOf(),
1254
+ label: minorFormatter(date),
1255
+ }))
1256
+ .filter((_, i, arr) => arr.length > this.X_MINOR_TICK_LIMIT
1257
+ ? i % Math.round(arr.length / this.X_MINOR_TICK_LIMIT) === 0
1258
+ : true);
1259
+ const xMajorInterval = getMajorInterval(binInterval);
1260
+ const xMajorIntervalFormat = getMajorIntervalFormat(xMajorInterval);
1261
+ const timeInterval = getTimeInterval(xMajorInterval);
1262
+ const tickFloor = timeInterval.floor(minDateValue);
1263
+ const tickCeiling = timeInterval.ceil(timeDay.offset(maxDateValue, 1));
1264
+ const majorFormatter = timeFormat(xMajorIntervalFormat);
1265
+ const xMajorTicks = timeInterval
1266
+ .range(tickFloor, tickCeiling)
1267
+ .map(tickDate => ({
1268
+ label: xMajorInterval === binInterval ? '' : majorFormatter(tickDate),
1269
+ value: tickDate.valueOf(),
1270
+ }));
1271
+ const x = { xMax: maxDateValue, xScale, xMinorTicks, xMajorTicks };
1272
+ const [y1, y2] = binnedData.map(config => {
1273
+ var _a, _b;
1274
+ const flattenedValues = config.series.reduce((values, series) => [
1275
+ ...values,
1276
+ ...series.data.map(({ value }) => value),
1277
+ ], []);
1278
+ const yMax = (_a = config.max) !== null && _a !== void 0 ? _a : Math.max(...flattenedValues);
1279
+ const yMin = (_b = config.min) !== null && _b !== void 0 ? _b : Math.min(...flattenedValues, 0);
1280
+ const yScale = scaleLinear()
1281
+ .domain([yMin, yMax])
1282
+ .range([
1283
+ height -
1284
+ this.BOTTOM_OFFSET -
1285
+ (this.BOTTOM_PADDING + this.TOP_PADDING),
1286
+ this.TOP_PADDING,
1287
+ ]);
1288
+ const yTicks = yScale.ticks(this.Y_TICK_COUNT);
1289
+ const series = config.series.map(series => (Object.assign(Object.assign({}, series), { path: line()
1290
+ .x(d => xScale(d.date))
1291
+ .y(d => yScale(d.value))(series.data), stroke: `var(${series.colorToken})`, markers: series.data.map(point => (Object.assign(Object.assign({}, point), { x: xScale(point.date), y: yScale(point.value) }))) })));
1292
+ return Object.assign(Object.assign({}, config), { series,
1293
+ yMax,
1294
+ yMin,
1295
+ yScale,
1296
+ yTicks });
1297
+ });
1298
+ // If we have a y2, coerce y1's ticks to be visually equivalent to y2's ticks.
1299
+ if (y2 === null || y2 === void 0 ? void 0 : y2.yTicks) {
1300
+ const tickConversionScale = scaleLinear()
1301
+ .range(y1.yScale.domain())
1302
+ .domain(y2.yScale.domain());
1303
+ y1.yTicks = y2.yTicks.map(tickConversionScale);
1304
+ }
1305
+ return { viewBox, x, y1, y2 };
1306
+ }), shareReplay({ refCount: true, bufferSize: 1 }));
1307
+ this.legend$ = this.binnedData$.pipe(map(binnedData => binnedData.reduce((items, config) => [
1308
+ ...items,
1309
+ ...config.series.map(series => ({
1310
+ label: series.label,
1311
+ colorToken: series.colorToken,
1312
+ })),
1313
+ ], [])));
1314
+ this.empty$ = this.binnedData$.pipe(map(binnedData => binnedData.every(config => config.series.every(series => series.data.length === 0))), shareReplay({ refCount: true, bufferSize: 1 }));
1315
+ this.hoveredMarker$ = new BehaviorSubject(null);
1316
+ this.callout$ = combineLatest([this.hoveredMarker$, this.drawData$]).pipe(map(([hoveredMarker, drawData]) => {
1317
+ if (!hoveredMarker)
1318
+ return null;
1319
+ const { target } = hoveredMarker.event;
1320
+ if (!target)
1321
+ return null;
1322
+ const markerRect = target.getBoundingClientRect();
1323
+ const padding = 8;
1324
+ const anchor = new DOMRect(markerRect.left - padding, markerRect.top - padding, markerRect.width + padding * 2, markerRect.height + padding * 2);
1325
+ const metrics = [];
1326
+ for (const series of drawData.y1.series) {
1327
+ const match = series.markers.find(marker => marker.x === hoveredMarker.marker.x);
1328
+ if (match) {
1329
+ metrics.push({
1330
+ label: series.label,
1331
+ value: drawData.y1.valueFormatter(match.value),
1332
+ });
1333
+ }
1334
+ }
1335
+ if (drawData.y2) {
1336
+ for (const series of drawData.y2.series) {
1337
+ const match = series.markers.find(marker => marker.x === hoveredMarker.marker.x);
1338
+ if (match) {
1339
+ metrics.push({
1340
+ label: series.label,
1341
+ value: drawData.y2.valueFormatter(match.value),
1342
+ });
1343
+ }
1344
+ }
1345
+ }
1346
+ return { anchor, metrics };
1347
+ }));
1348
+ }
1349
+ set input(v) {
1350
+ this.input$.next(v);
1351
+ }
1352
+ get input() {
1353
+ return this.input$.getValue();
1354
+ }
1355
+ set width(v) {
1356
+ this.width$.next(v);
1357
+ }
1358
+ get width() {
1359
+ return this.width$.getValue();
1360
+ }
1361
+ set height(v) {
1362
+ this.height$.next(v);
1363
+ }
1364
+ get height() {
1365
+ return this.height$.getValue();
1366
+ }
1367
+ }
1368
+ TimeSeriesComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: TimeSeriesComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1369
+ TimeSeriesComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: TimeSeriesComponent, selector: "riv-time-series", inputs: { input: "input", width: "width", height: "height" }, ngImport: i0, template: "<div *ngIf=\"!(empty$ | async); else zeroState\" class=\"container\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n *ngIf=\"drawData$ | async; let d\"\n [attr.viewBox]=\"d.viewBox\"\n >\n <g *ngFor=\"let tick of d.x.xMajorTicks\">\n <rect\n class=\"tick\"\n [attr.x]=\"d.x.xScale(tick.value)\"\n y=\"0\"\n width=\"1\"\n [attr.height]=\"d.y1.yScale(d.y1.yMin)\"\n ></rect>\n <text\n class=\"x-major-tick-label\"\n [attr.x]=\"d.x.xScale(tick.value)\"\n [attr.y]=\"d.y1.yScale(d.y1.yMin)\"\n dx=\"4\"\n dy=\"-4\"\n >\n {{ tick.label }}\n </text>\n </g>\n <g *ngFor=\"let tick of d.x.xMinorTicks\">\n <text\n class=\"x-minor-tick-label\"\n [attr.x]=\"d.x.xScale(tick.value)\"\n [attr.y]=\"d.y1.yScale(d.y1.yMin)\"\n text-anchor=\"middle\"\n dominant-baseline=\"hanging\"\n dy=\"8\"\n >\n {{ tick.label }}\n <title>{{ tick.value | date }}</title>\n </text>\n </g>\n <g *ngFor=\"let tick of d.y1.yTicks\">\n <rect\n class=\"tick\"\n x=\"0\"\n [attr.y]=\"d.y1.yScale(tick)\"\n width=\"100%\"\n height=\"1\"\n ></rect>\n <text class=\"y-tick-label\" x=\"0\" [attr.y]=\"d.y1.yScale(tick)\" dy=\"-4\">\n {{ d.y1.valueFormatter(tick) }}\n </text>\n </g>\n\n <g *ngFor=\"let tick of d.y2?.yTicks\">\n <text\n class=\"y-tick-label\"\n [attr.x]=\"d.x.xScale(d.x.xMax)\"\n [attr.y]=\"d.y2?.yScale(tick)\"\n text-anchor=\"end\"\n dy=\"-4\"\n >\n {{ d.y2?.valueFormatter(tick) }}\n </text>\n </g>\n\n <g *ngIf=\"hoveredMarker$ | async; let hoveredMarker\">\n <line\n class=\"hover-rule\"\n [attr.x1]=\"hoveredMarker.marker.x\"\n [attr.y1]=\"d.y1.yScale(d.y1.yMin)\"\n [attr.x2]=\"hoveredMarker.marker.x\"\n [attr.y2]=\"d.y1.yScale(d.y1.yMax)\"\n stroke-width=\"2\"\n stroke-dasharray=\"4\"\n />\n </g>\n\n <ng-template #seriesTpl let-series=\"series\">\n <path\n class=\"data path\"\n [class.marker-hovered]=\"!!(hoveredMarker$ | async)\"\n [attr.d]=\"series.path\"\n fill=\"none\"\n stroke-width=\"2\"\n [attr.stroke]=\"series.stroke\"\n [attr.stroke-dasharray]=\"series.style === 'dashed' ? '4' : null\"\n ></path>\n <circle\n *ngFor=\"let marker of series.markers\"\n class=\"data marker\"\n [class.focused]=\"(hoveredMarker$ | async)?.marker?.x === marker.x\"\n [class.blurred]=\"\n (hoveredMarker$ | async) !== null &&\n (hoveredMarker$ | async)?.marker?.x !== marker.x\n \"\n [attr.cx]=\"marker.x\"\n [attr.cy]=\"marker.y\"\n r=\"3.5\"\n stroke-width=\"2\"\n [attr.stroke]=\"series.stroke\"\n (mouseover)=\"hoveredMarker$.next({ event: $event, marker: marker })\"\n (mouseleave)=\"hoveredMarker$.next(null)\"\n ></circle>\n </ng-template>\n <g *ngFor=\"let series of d.y1.series\">\n <ng-container\n *ngTemplateOutlet=\"seriesTpl; context: { series: series }\"\n ></ng-container>\n </g>\n <g *ngFor=\"let series of d.y2?.series\">\n <ng-container\n *ngTemplateOutlet=\"seriesTpl; context: { series: series }\"\n ></ng-container>\n </g>\n </svg>\n <legend>\n <riv-legend-item\n *ngFor=\"let item of legend$ | async\"\n [label]=\"item.label\"\n [colorToken]=\"item.colorToken\"\n ></riv-legend-item>\n </legend>\n</div>\n\n<ng-container *ngIf=\"callout$ | async; let callout\">\n <riv-callout\n *riv-callout\n [anchor]=\"callout.anchor\"\n [isModal]=\"false\"\n [preferredPosition]=\"'top-center'\"\n >\n <div class=\"callout-content\">\n <div class=\"callout-metric\" *ngFor=\"let metric of callout.metrics\">\n <div>{{ metric.label }}</div>\n <div class=\"callout-metric-value\">{{ metric.value }}</div>\n </div>\n </div>\n </riv-callout>\n</ng-container>\n\n<ng-template #zeroState>\n <riv-zero-state></riv-zero-state>\n</ng-template>\n", styles: [".container{display:flex;flex-direction:column;gap:var(--size-xlarge)}.y-tick-label,.x-major-tick-label{font-size:var(--type-0-font-size);line-height:var(--type-0-line-height-0);fill:var(--type-light-low-contrast)}.x-minor-tick-label{font-size:var(--type-1-font-size);line-height:var(--type-1-line-height-0);fill:var(--type-light-low-contrast);text-anchor:middle}.tick{fill:var(--gray-20)}.data.path{transition:stroke-opacity var(--short-transition)}.data.path.marker-hovered{stroke-opacity:.4}.data.marker{fill:var(--surface-light-0);transition:stroke-opacity var(--short-transition)}.data.marker.focused{stroke-opacity:1;filter:drop-shadow(0 1px 1px rgba(10,2,22,.15))}.data.marker.blurred{stroke-opacity:.4}.hover-rule{stroke:var(--gray-20)}legend{display:flex;flex-wrap:wrap;gap:var(--size-large);justify-content:flex-start;align-items:baseline}.callout-content{padding:var(--size-large);display:flex;gap:var(--size-medium)}.callout-metric{display:flex;flex-direction:column;gap:var(--size-xsmall);font-size:var(--type-1-font-size);line-height:var(--type-1-line-height-0)}.callout-metric-value{font-weight:var(--font-weight-heavy)}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: CalloutComponent, selector: "riv-callout", inputs: ["anchor", "isModal", "preferredPosition", "allowedPositions", "fallbackDirection", "showCaret", "theme"], outputs: ["close"] }, { kind: "directive", type: CalloutDirective, selector: "[riv-callout]" }, { kind: "component", type: LegendItemComponent, selector: "riv-legend-item", inputs: ["label", "colorToken", "style", "visibility", "iconTooltip"], outputs: ["itemClick"] }, { kind: "component", type: ZeroStateComponent, selector: "riv-zero-state", inputs: ["message"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i1.DatePipe, name: "date" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1370
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: TimeSeriesComponent, decorators: [{
1371
+ type: Component,
1372
+ args: [{ selector: 'riv-time-series', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div *ngIf=\"!(empty$ | async); else zeroState\" class=\"container\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n *ngIf=\"drawData$ | async; let d\"\n [attr.viewBox]=\"d.viewBox\"\n >\n <g *ngFor=\"let tick of d.x.xMajorTicks\">\n <rect\n class=\"tick\"\n [attr.x]=\"d.x.xScale(tick.value)\"\n y=\"0\"\n width=\"1\"\n [attr.height]=\"d.y1.yScale(d.y1.yMin)\"\n ></rect>\n <text\n class=\"x-major-tick-label\"\n [attr.x]=\"d.x.xScale(tick.value)\"\n [attr.y]=\"d.y1.yScale(d.y1.yMin)\"\n dx=\"4\"\n dy=\"-4\"\n >\n {{ tick.label }}\n </text>\n </g>\n <g *ngFor=\"let tick of d.x.xMinorTicks\">\n <text\n class=\"x-minor-tick-label\"\n [attr.x]=\"d.x.xScale(tick.value)\"\n [attr.y]=\"d.y1.yScale(d.y1.yMin)\"\n text-anchor=\"middle\"\n dominant-baseline=\"hanging\"\n dy=\"8\"\n >\n {{ tick.label }}\n <title>{{ tick.value | date }}</title>\n </text>\n </g>\n <g *ngFor=\"let tick of d.y1.yTicks\">\n <rect\n class=\"tick\"\n x=\"0\"\n [attr.y]=\"d.y1.yScale(tick)\"\n width=\"100%\"\n height=\"1\"\n ></rect>\n <text class=\"y-tick-label\" x=\"0\" [attr.y]=\"d.y1.yScale(tick)\" dy=\"-4\">\n {{ d.y1.valueFormatter(tick) }}\n </text>\n </g>\n\n <g *ngFor=\"let tick of d.y2?.yTicks\">\n <text\n class=\"y-tick-label\"\n [attr.x]=\"d.x.xScale(d.x.xMax)\"\n [attr.y]=\"d.y2?.yScale(tick)\"\n text-anchor=\"end\"\n dy=\"-4\"\n >\n {{ d.y2?.valueFormatter(tick) }}\n </text>\n </g>\n\n <g *ngIf=\"hoveredMarker$ | async; let hoveredMarker\">\n <line\n class=\"hover-rule\"\n [attr.x1]=\"hoveredMarker.marker.x\"\n [attr.y1]=\"d.y1.yScale(d.y1.yMin)\"\n [attr.x2]=\"hoveredMarker.marker.x\"\n [attr.y2]=\"d.y1.yScale(d.y1.yMax)\"\n stroke-width=\"2\"\n stroke-dasharray=\"4\"\n />\n </g>\n\n <ng-template #seriesTpl let-series=\"series\">\n <path\n class=\"data path\"\n [class.marker-hovered]=\"!!(hoveredMarker$ | async)\"\n [attr.d]=\"series.path\"\n fill=\"none\"\n stroke-width=\"2\"\n [attr.stroke]=\"series.stroke\"\n [attr.stroke-dasharray]=\"series.style === 'dashed' ? '4' : null\"\n ></path>\n <circle\n *ngFor=\"let marker of series.markers\"\n class=\"data marker\"\n [class.focused]=\"(hoveredMarker$ | async)?.marker?.x === marker.x\"\n [class.blurred]=\"\n (hoveredMarker$ | async) !== null &&\n (hoveredMarker$ | async)?.marker?.x !== marker.x\n \"\n [attr.cx]=\"marker.x\"\n [attr.cy]=\"marker.y\"\n r=\"3.5\"\n stroke-width=\"2\"\n [attr.stroke]=\"series.stroke\"\n (mouseover)=\"hoveredMarker$.next({ event: $event, marker: marker })\"\n (mouseleave)=\"hoveredMarker$.next(null)\"\n ></circle>\n </ng-template>\n <g *ngFor=\"let series of d.y1.series\">\n <ng-container\n *ngTemplateOutlet=\"seriesTpl; context: { series: series }\"\n ></ng-container>\n </g>\n <g *ngFor=\"let series of d.y2?.series\">\n <ng-container\n *ngTemplateOutlet=\"seriesTpl; context: { series: series }\"\n ></ng-container>\n </g>\n </svg>\n <legend>\n <riv-legend-item\n *ngFor=\"let item of legend$ | async\"\n [label]=\"item.label\"\n [colorToken]=\"item.colorToken\"\n ></riv-legend-item>\n </legend>\n</div>\n\n<ng-container *ngIf=\"callout$ | async; let callout\">\n <riv-callout\n *riv-callout\n [anchor]=\"callout.anchor\"\n [isModal]=\"false\"\n [preferredPosition]=\"'top-center'\"\n >\n <div class=\"callout-content\">\n <div class=\"callout-metric\" *ngFor=\"let metric of callout.metrics\">\n <div>{{ metric.label }}</div>\n <div class=\"callout-metric-value\">{{ metric.value }}</div>\n </div>\n </div>\n </riv-callout>\n</ng-container>\n\n<ng-template #zeroState>\n <riv-zero-state></riv-zero-state>\n</ng-template>\n", styles: [".container{display:flex;flex-direction:column;gap:var(--size-xlarge)}.y-tick-label,.x-major-tick-label{font-size:var(--type-0-font-size);line-height:var(--type-0-line-height-0);fill:var(--type-light-low-contrast)}.x-minor-tick-label{font-size:var(--type-1-font-size);line-height:var(--type-1-line-height-0);fill:var(--type-light-low-contrast);text-anchor:middle}.tick{fill:var(--gray-20)}.data.path{transition:stroke-opacity var(--short-transition)}.data.path.marker-hovered{stroke-opacity:.4}.data.marker{fill:var(--surface-light-0);transition:stroke-opacity var(--short-transition)}.data.marker.focused{stroke-opacity:1;filter:drop-shadow(0 1px 1px rgba(10,2,22,.15))}.data.marker.blurred{stroke-opacity:.4}.hover-rule{stroke:var(--gray-20)}legend{display:flex;flex-wrap:wrap;gap:var(--size-large);justify-content:flex-start;align-items:baseline}.callout-content{padding:var(--size-large);display:flex;gap:var(--size-medium)}.callout-metric{display:flex;flex-direction:column;gap:var(--size-xsmall);font-size:var(--type-1-font-size);line-height:var(--type-1-line-height-0)}.callout-metric-value{font-weight:var(--font-weight-heavy)}\n"] }]
1373
+ }], propDecorators: { input: [{
1374
+ type: Input
1375
+ }], width: [{
1376
+ type: Input
1377
+ }], height: [{
1378
+ type: Input
1379
+ }] } });
1380
+
1195
1381
  class RivModule {
1196
1382
  }
1197
1383
  RivModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: RivModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
@@ -1202,13 +1388,19 @@ RivModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.
1202
1388
  DataTableComponent,
1203
1389
  DataTableHeaderCellComponent,
1204
1390
  DataTableRowComponent,
1391
+ DaysPipe,
1205
1392
  DonutComponent,
1206
1393
  IconComponent,
1207
1394
  LegendItemComponent,
1208
1395
  MetricComponent,
1396
+ NumberPipe,
1397
+ PercentagePipe,
1398
+ SmallCurrencyPipe,
1209
1399
  StackedColumnComponent,
1210
1400
  TextToggleComponent,
1211
1401
  TimeSeriesComponent,
1402
+ TooltipComponent,
1403
+ TooltipDirective,
1212
1404
  ZeroStateComponent], imports: [CommonModule], exports: [CalloutComponent,
1213
1405
  CalloutDirective,
1214
1406
  CalloutOutletComponent,
@@ -1216,13 +1408,19 @@ RivModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.
1216
1408
  DataTableComponent,
1217
1409
  DataTableHeaderCellComponent,
1218
1410
  DataTableRowComponent,
1411
+ DaysPipe,
1219
1412
  DonutComponent,
1220
1413
  IconComponent,
1221
1414
  LegendItemComponent,
1222
1415
  MetricComponent,
1416
+ NumberPipe,
1417
+ PercentagePipe,
1418
+ SmallCurrencyPipe,
1223
1419
  StackedColumnComponent,
1224
1420
  TextToggleComponent,
1225
1421
  TimeSeriesComponent,
1422
+ TooltipComponent,
1423
+ TooltipDirective,
1226
1424
  ZeroStateComponent] });
1227
1425
  RivModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: RivModule, imports: [CommonModule] });
1228
1426
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: RivModule, decorators: [{
@@ -1236,13 +1434,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
1236
1434
  DataTableComponent,
1237
1435
  DataTableHeaderCellComponent,
1238
1436
  DataTableRowComponent,
1437
+ DaysPipe,
1239
1438
  DonutComponent,
1240
1439
  IconComponent,
1241
1440
  LegendItemComponent,
1242
1441
  MetricComponent,
1442
+ NumberPipe,
1443
+ PercentagePipe,
1444
+ SmallCurrencyPipe,
1243
1445
  StackedColumnComponent,
1244
1446
  TextToggleComponent,
1245
1447
  TimeSeriesComponent,
1448
+ TooltipComponent,
1449
+ TooltipDirective,
1246
1450
  ZeroStateComponent,
1247
1451
  ],
1248
1452
  exports: [
@@ -1253,13 +1457,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
1253
1457
  DataTableComponent,
1254
1458
  DataTableHeaderCellComponent,
1255
1459
  DataTableRowComponent,
1460
+ DaysPipe,
1256
1461
  DonutComponent,
1257
1462
  IconComponent,
1258
1463
  LegendItemComponent,
1259
1464
  MetricComponent,
1465
+ NumberPipe,
1466
+ PercentagePipe,
1467
+ SmallCurrencyPipe,
1260
1468
  StackedColumnComponent,
1261
1469
  TextToggleComponent,
1262
1470
  TimeSeriesComponent,
1471
+ TooltipComponent,
1472
+ TooltipDirective,
1263
1473
  ZeroStateComponent,
1264
1474
  ],
1265
1475
  imports: [CommonModule],
@@ -1270,5 +1480,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
1270
1480
  * Generated bundle index. Do not edit.
1271
1481
  */
1272
1482
 
1273
- export { CalloutComponent, CalloutDirective, CalloutOutletComponent, DataTableCellComponent, DataTableComponent, DataTableHeaderCellComponent, DataTableRowComponent, DonutComponent, IconComponent, LegendItemComponent, MetricComponent, RivModule, StackedColumnComponent, TextToggleComponent, TimeSeriesComponent, ZeroStateComponent };
1483
+ export { CalloutComponent, CalloutDirective, CalloutOutletComponent, DataTableCellComponent, DataTableComponent, DataTableHeaderCellComponent, DataTableRowComponent, DaysPipe, DonutComponent, IconComponent, LegendItemComponent, MetricComponent, NumberPipe, PercentagePipe, RivModule, SmallCurrencyPipe, StackedColumnComponent, TextToggleComponent, TimeSeriesComponent, TooltipComponent, TooltipDirective, ZeroStateComponent };
1274
1484
  //# sourceMappingURL=rivet-health-design-system.mjs.map