cats-charts 0.0.85 → 0.0.87
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/cats-charts.mjs +275 -36
- package/fesm2022/cats-charts.mjs.map +1 -1
- package/index.d.ts +23 -5
- package/package.json +1 -1
package/fesm2022/cats-charts.mjs
CHANGED
|
@@ -446,11 +446,11 @@ class ChartLegendComponent {
|
|
|
446
446
|
return typeof this.config.maxWidth === 'string' && this.config.maxWidth.trim().length > 0;
|
|
447
447
|
}
|
|
448
448
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ChartLegendComponent, deps: [{ token: ChartLegendAdapter }, { token: i0.ChangeDetectorRef }, { token: PLATFORM_ID }], target: i0.ɵɵFactoryTarget.Component });
|
|
449
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: ChartLegendComponent, isStandalone: true, selector: "lib-chart-legend", inputs: { chart: "chart", series: "series", colors: "colors", config: "config", itemTemplate: "itemTemplate" }, outputs: { legendEvent: "legendEvent" }, viewQueries: [{ propertyName: "itemsScroller", first: true, predicate: ["itemsScroller"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "@if (config.enabled !== false) {\r\n <nav\r\n class=\"chart-legend\"\r\n [class.chart-legend--vertical]=\"isVerticalLegend\"\r\n [class.chart-legend--scrollable]=\"isScrollableLegend\"\r\n [class.chart-legend--wrap]=\"!isScrollableLegend\"\r\n [class.chart-legend--limited-wrap]=\"isLimitedWrapLegend\"\r\n [ngClass]=\"config.className || null\"\r\n [style.max-height]=\"config.maxHeight || null\"\r\n [style.padding]=\"config.padding || '1rem'\"\r\n [attr.aria-label]=\"config.ariaLabel || 'Chart legend'\"\r\n >\r\n <div class=\"chart-legend__viewport\">\r\n @if (config.title) {\r\n <p\r\n class=\"chart-legend-title\"\r\n [class.chart-legend-title--uppercase]=\"config.legendTitleTransform === 'uppercase'\"\r\n [class.chart-legend-title--lowercase]=\"config.legendTitleTransform === 'lowercase'\"\r\n [class.chart-legend-title--capitalize]=\"config.legendTitleTransform === 'capitalize'\"\r\n [style.--legend-title-color]=\"config.legendTitleTextColor || null\"\r\n [style.--legend-title-font-size]=\"\r\n config.legendTitleFontSize ? config.legendTitleFontSize + 'px' : null\r\n \"\r\n [style.--legend-title-font-style]=\"config.legendTitleFontStyle || null\"\r\n [style.--legend-title-font-weight]=\"config.legendTitleFontWeight || null\"\r\n [style.--legend-title-text-decoration]=\"config.legendTitleTextDecoration || null\"\r\n [style.--legend-title-font-family]=\"config.legendTitleFontFamily || 'initial'\"\r\n >\r\n {{ config.title }}\r\n </p>\r\n }\r\n @if (usesInternalLegendScroll && canScrollLegend) {\r\n <button\r\n type=\"button\"\r\n class=\"chart-legend__scroll-button chart-legend__scroll-button--start\"\r\n [disabled]=\"!canScrollStart\"\r\n (click)=\"scrollLegend(-1, $event)\"\r\n [attr.aria-label]=\"scrollStartAriaLabel\"\r\n >\r\n <img\r\n src=\"images/legend_left.svg\"\r\n [class.chart-legend__scroll-icon--up]=\"scrollsVertically\"\r\n alt=\"left\"\r\n />\r\n </button>\r\n }\r\n\r\n <div #itemsScroller class=\"chart-legend__scroller\" (scroll)=\"updateScrollState()\">\r\n <div\r\n class=\"chart-legend__items\"\r\n role=\"list\"\r\n [class.chart-legend__items--center]=\"\r\n isLegendAlignedCenter && (!usesInternalLegendScroll || !canScrollLegend)\r\n \"\r\n [class.chart-legend__items--end]=\"isLegendAlignedEnd\"\r\n [style.--legend-text-color]=\"config.legendTextColor || null\"\r\n [style.--legend-font-size]=\"config.legendFontSize ? config.legendFontSize + 'px' : null\"\r\n [style.--legend-font-style]=\"config.legendFontStyle || null\"\r\n [style.--legend-font-weight]=\"config.legendFontWeight || null\"\r\n [style.--legend-text-decoration]=\"config.legendTextDecoration || null\"\r\n [style.--legend-font-family]=\"config.legendFontFamily || 'initial'\"\r\n >\r\n @for (group of groupedItems; track trackByGroup($index, group)) {\r\n @if (group.group) {\r\n <div class=\"chart-legend__group-label\">{{ group.group }}</div>\r\n }\r\n\r\n @for (item of group.items; track trackByItem($index, item)) {\r\n <button\r\n type=\"button\"\r\n class=\"chart-legend__item\"\r\n role=\"switch\"\r\n [class.chart-legend__item--off]=\"!item.selected\"\r\n [class.chart-legend__item--disabled]=\"item.disabled\"\r\n [class.chart-legend__item--hovered]=\"state.hoveredName === item.name\"\r\n [disabled]=\"item.disabled\"\r\n [attr.aria-checked]=\"item.selected\"\r\n [attr.aria-label]=\"item.label\"\r\n [style.--legend-item-color]=\"item.color\"\r\n [title]=\"itemTitle(item)\"\r\n (click)=\"toggle(item, $event)\"\r\n (keydown.enter)=\"toggle(item, $event)\"\r\n (keydown.space)=\"toggle(item, $event)\"\r\n (mouseenter)=\"hover(item)\"\r\n (focus)=\"hover(item)\"\r\n (mouseleave)=\"leave(item)\"\r\n (blur)=\"leave(item)\"\r\n >\r\n @if (templateFor(item); as template) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"template\"\r\n [ngTemplateOutletContext]=\"templateContext(item)\"\r\n ></ng-container>\r\n } @else {\r\n @switch (iconRenderType(item)) {\r\n @case ('image') {\r\n @if (isLineMarker(item)) {\r\n <span\r\n class=\"chart-legend__icon chart-legend__icon--line-marker\"\r\n aria-hidden=\"true\"\r\n >\r\n <span class=\"chart-legend__icon-line\"></span>\r\n <img class=\"chart-legend__icon-image\" [src]=\"iconImageSrc(item)\" alt=\"\" />\r\n <span class=\"chart-legend__icon-line\"></span>\r\n </span>\r\n } @else {\r\n <img class=\"chart-legend__icon-image\" [src]=\"iconImageSrc(item)\" alt=\"\" />\r\n }\r\n }\r\n @case ('path') {\r\n @if (isLineMarker(item)) {\r\n <span\r\n class=\"chart-legend__icon chart-legend__icon--line-marker\"\r\n aria-hidden=\"true\"\r\n >\r\n <span class=\"chart-legend__icon-line\"></span>\r\n <svg\r\n class=\"chart-legend__icon-path\"\r\n viewBox=\"-512 -512 1024 1024\"\r\n aria-hidden=\"true\"\r\n >\r\n <path [attr.d]=\"iconPathData(item)\"></path>\r\n </svg>\r\n <span class=\"chart-legend__icon-line\"></span>\r\n </span>\r\n } @else {\r\n <svg\r\n class=\"chart-legend__icon-path\"\r\n viewBox=\"-512 -512 1024 1024\"\r\n aria-hidden=\"true\"\r\n >\r\n <path [attr.d]=\"iconPathData(item)\"></path>\r\n </svg>\r\n }\r\n }\r\n @case ('shape') {\r\n @if (isLineMarker(item)) {\r\n <span\r\n class=\"chart-legend__icon chart-legend__icon--line-marker\"\r\n aria-hidden=\"true\"\r\n >\r\n <span class=\"chart-legend__icon-line\"></span>\r\n <span\r\n class=\"chart-legend__icon chart-legend__icon--marker\"\r\n [ngClass]=\"iconShapeClass(item.icon)\"\r\n ></span>\r\n <span class=\"chart-legend__icon-line\"></span>\r\n </span>\r\n } @else {\r\n <span\r\n class=\"chart-legend__icon\"\r\n [ngClass]=\"iconShapeClass(iconForRender(item))\"\r\n aria-hidden=\"true\"\r\n ></span>\r\n }\r\n }\r\n }\r\n <span class=\"chart-legend__label\"\r\n >{{ item.label\r\n }}{{ this.config.showValue && this.config.valueFormatter && ':' }}</span\r\n >\r\n @if (this.config.showValue && this.config.valueFormatter) {\r\n <span class=\"chart-legend__value\">{{ this.config.valueFormatter(item) }}</span>\r\n }\r\n @if (this.config.showActionArrow) {\r\n @if (this.config.actionArrowTemplate) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"this.config.actionArrowTemplate\"\r\n [ngTemplateOutletContext]=\"templateContext(item)\"\r\n ></ng-container>\r\n } @else {\r\n <svg\r\n class=\"chart-legend__action-arrow\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n >\r\n <polyline points=\"9 18 15 12 9 6\"></polyline>\r\n </svg>\r\n }\r\n }\r\n }\r\n </button>\r\n }\r\n }\r\n </div>\r\n </div>\r\n\r\n @if (usesInternalLegendScroll && canScrollLegend) {\r\n <button\r\n type=\"button\"\r\n class=\"chart-legend__scroll-button chart-legend__scroll-button--end\"\r\n [disabled]=\"!canScrollEnd\"\r\n (click)=\"scrollLegend(1, $event)\"\r\n [attr.aria-label]=\"scrollEndAriaLabel\"\r\n >\r\n <img\r\n src=\"images/legend_right.svg\"\r\n [class.chart-legend__scroll-icon--down]=\"scrollsVertically\"\r\n alt=\"right\"\r\n />\r\n </button>\r\n }\r\n </div>\r\n\r\n @if (config.showPagination && pageCount > 1) {\r\n <div class=\"chart-legend__pagination\" aria-label=\"Legend pages\">\r\n <button\r\n type=\"button\"\r\n class=\"chart-legend__page\"\r\n [disabled]=\"state.pageIndex === 0\"\r\n (click)=\"page(-1)\"\r\n aria-label=\"Previous legend page\"\r\n >\r\n <\r\n </button>\r\n <span class=\"chart-legend__page-count\">{{ state.pageIndex + 1 }} / {{ pageCount }}</span>\r\n <button\r\n type=\"button\"\r\n class=\"chart-legend__page\"\r\n [disabled]=\"state.pageIndex + 1 === pageCount\"\r\n (click)=\"page(1)\"\r\n aria-label=\"Next legend page\"\r\n >\r\n >\r\n </button>\r\n </div>\r\n }\r\n </nav>\r\n}\r\n", styles: [":host{display:block;min-height:0;min-width:0}.chart-legend{--legend-text-color: #040d17;--legend-muted-color: #8a94a6;--legend-border-color: #eaf3fd;--legend-hover-bg: rgba(15, 23, 42, .04);--legend-font-size: 14px;--legend-item-min-height: 28px;--legend-row-gap: 8px;--legend-column-gap: 12px;--legend-font-style: normal;--legend-font-weight: 400;--legend-text-decoration: none;--legend-font-family: initial;--legend-title-color: #040d17;--legend-title-font-size: 14px;--legend-title-font-style: normal;--legend-title-font-weight: 400;--legend-title-text-decoration: none;--legend-title-font-family: initial;box-sizing:border-box;min-height:0;min-width:0;width:100%}:host-context(.dark) .chart-legend,:host-context([data-theme=dark]) .chart-legend{--legend-text-color: #e5e7eb;--legend-muted-color: #9ca3af;--legend-border-color: #374151;--legend-hover-bg: rgba(255, 255, 255, .08)}.chart-legend__viewport{align-items:center;display:flex;gap:4px;min-width:0;width:100%}.chart-legend__viewport .chart-legend-title{font-weight:var(--legend-title-font-weight);font-size:var(--legend-title-font-size);font-style:var(--legend-title-font-style);text-decoration:var(--legend-title-text-decoration);font-family:var(--legend-title-font-family);color:var(--legend-title-color);white-space:nowrap;margin:0 8px 0 0}.chart-legend__viewport .chart-legend-title--uppercase{text-transform:uppercase}.chart-legend__viewport .chart-legend-title--lowercase{text-transform:lowercase}.chart-legend__viewport .chart-legend-title--capitalize{text-transform:capitalize}.chart-legend__scroller{flex:1 1 auto;min-height:0;min-width:0;overflow-x:hidden;overflow-y:hidden;scrollbar-width:none}.chart-legend__scroller::-webkit-scrollbar{display:none}.chart-legend--scrollable .chart-legend__scroller{overflow-x:auto;overscroll-behavior-x:contain}.chart-legend--scrollable .chart-legend__scroller::-webkit-scrollbar{display:block;height:6px}.chart-legend__items{display:flex;flex-wrap:nowrap;align-items:center;gap:var(--legend-row-gap) var(--legend-column-gap);min-width:0;color:var(--legend-text-color);font-size:var(--legend-font-size);font-style:var(--legend-font-style);font-weight:var(--legend-font-weight);text-decoration:var(--legend-text-decoration);font-family:var(--legend-font-family)}.chart-legend--scrollable .chart-legend__items{min-width:max-content}.chart-legend--wrap:not(.chart-legend--vertical) .chart-legend__items{flex-wrap:wrap;width:100%}.chart-legend--limited-wrap:not(.chart-legend--vertical) .chart-legend__scroller{max-height:calc(var(--legend-item-min-height) * 2 + var(--legend-row-gap));overflow-y:auto;overscroll-behavior-y:contain}.chart-legend--vertical{height:100%}.chart-legend--vertical .chart-legend__viewport{align-items:stretch;flex-direction:column;height:100%;min-height:0}.chart-legend--vertical .chart-legend__scroller{overflow-x:hidden;overflow-y:hidden}.chart-legend--vertical.chart-legend--scrollable .chart-legend__scroller{overflow-y:auto;overscroll-behavior-y:contain}.chart-legend--vertical .chart-legend__items{align-items:stretch;flex-direction:column;min-width:0;width:100%;height:100%}.chart-legend--vertical.chart-legend--wrap .chart-legend__items{align-content:start;display:grid;grid-auto-flow:column;grid-auto-columns:max-content;grid-template-rows:repeat(auto-fit,minmax(28px,max-content));height:100%;justify-content:start;width:auto}.chart-legend--vertical.chart-legend--limited-wrap .chart-legend__viewport{flex-direction:row}.chart-legend--vertical.chart-legend--limited-wrap .chart-legend__scroller{overflow-x:auto;overflow-y:hidden;overscroll-behavior-x:contain}.chart-legend--vertical.chart-legend--limited-wrap .chart-legend__items{grid-auto-columns:minmax(1,calc((100% - var(--legend-column-gap)) / 2));width:max-content}.chart-legend__items--center{justify-content:center}.chart-legend__items--end{justify-content:flex-end}.chart-legend--vertical.chart-legend--wrap .chart-legend__items--center{align-content:center;justify-content:start}.chart-legend--vertical.chart-legend--wrap .chart-legend__items--end{align-content:end;justify-content:start}.chart-legend__group-label{flex:0 0 auto;color:var(--legend-muted-color);font-size:12px;font-weight:600;line-height:1.2;margin-top:4px}.chart-legend__item{--legend-item-color: #64748b;align-items:center;background:color-mix(in srgb,var(--legend-item-color) 4%,transparent);border:1px solid color-mix(in srgb,var(--legend-item-color) 25%,transparent);border-radius:4px;color:inherit;cursor:pointer;display:inline-flex;font:inherit;gap:8px;line-height:1.2;min-height:28px;min-width:0;padding:4px 8px;touch-action:manipulation;transition:background-color .14s ease,border-color .14s ease,opacity .14s ease}.chart-legend--vertical .chart-legend__item{justify-content:flex-start;width:100%}.chart-legend--vertical.chart-legend--wrap .chart-legend__item{width:auto}.chart-legend--vertical.chart-legend--limited-wrap .chart-legend__item{width:100%}.chart-legend__scroll-button{align-items:center;background:transparent;border:1px solid var(--legend-border-color);border-radius:6px;color:inherit;cursor:pointer;display:inline-flex;flex:0 0 auto;font:inherit;height:28px;justify-content:center;line-height:1;width:28px}.chart-legend--vertical .chart-legend__scroll-button{width:100%}.chart-legend--vertical.chart-legend--limited-wrap .chart-legend__scroll-button{height:auto;min-height:28px;width:28px}.chart-legend__scroll-button img{display:block;height:10px;width:10px}.chart-legend__scroll-icon--up,.chart-legend__scroll-icon--down{transform:rotate(90deg)}.chart-legend__scroll-button:disabled{cursor:default;opacity:.42}.chart-legend__item:hover,.chart-legend__item:focus-visible,.chart-legend__item--hovered{outline:none}.chart-legend__item--off{color:var(--legend-muted-color);filter:grayscale(1);opacity:.68}.chart-legend__item--disabled{cursor:not-allowed;opacity:.48}.chart-legend__icon,.chart-legend__icon-image,.chart-legend__icon-path{--legend-icon-size: 12px;background:var(--legend-item-color);box-sizing:border-box;display:inline-block;flex:0 0 auto;height:var(--legend-icon-size);width:var(--legend-icon-size)}.chart-legend__icon-image,.chart-legend__icon-path{background:transparent;object-fit:contain}.chart-legend__icon-path path{fill:var(--legend-item-color);stroke:var(--legend-item-color)}.chart-legend__icon--line,.chart-legend__icon--emptyLine{height:11px;border-radius:999px;background:linear-gradient(to bottom,transparent 0 4px,var(--legend-item-color) 4px 6px,transparent 6px 100%)}.chart-legend__icon--emptyLine{background:linear-gradient(to bottom,transparent 0 4px,var(--legend-item-color) 4px 6px,transparent 6px 100%)}.chart-legend__icon--area{background:linear-gradient(to bottom,var(--legend-item-color),color-mix(in srgb,var(--legend-item-color) 12%,transparent));border-top:3px solid var(--legend-item-color)}.chart-legend__icon--circle{border-radius:50%}.chart-legend__icon--emptyCircle{background:transparent;border:2px solid var(--legend-item-color);border-radius:50%}.chart-legend__icon--rect,.chart-legend__icon--emptyRect,.chart-legend__icon--square,.chart-legend__icon--emptySquare{border-radius:2px}.chart-legend__icon--emptyRect,.chart-legend__icon--emptySquare{background:transparent;border:2px solid var(--legend-item-color)}.chart-legend__icon--roundRect,.chart-legend__icon--emptyRoundRect{border-radius:6px}.chart-legend__icon--emptyRoundRect{background:transparent;border:2px solid var(--legend-item-color)}.chart-legend__icon--triangle,.chart-legend__icon--emptyTriangle{clip-path:polygon(50% 0,100% 100%,0 100%)}.chart-legend__icon--emptyTriangle{background:var(--legend-item-color)}.chart-legend__icon--diamond,.chart-legend__icon--emptyDiamond{transform:rotate(45deg)}.chart-legend__icon--emptyDiamond{background:transparent;border:2px solid var(--legend-item-color)}.chart-legend__icon--pin,.chart-legend__icon--emptyPin{border-radius:50% 50% 50% 0;transform:rotate(-45deg)}.chart-legend__icon--emptyPin{background:transparent;border:2px solid var(--legend-item-color)}.chart-legend__icon--arrow,.chart-legend__icon--emptyArrow{clip-path:polygon(0 35%,58% 35%,58% 10%,100% 50%,58% 90%,58% 65%,0 65%)}.chart-legend__icon--emptyArrow{opacity:.72}.chart-legend__icon--x,.chart-legend__icon--plus,.chart-legend__icon--thickLine{background:transparent;position:relative}.chart-legend__icon--x:before,.chart-legend__icon--x:after,.chart-legend__icon--plus:before,.chart-legend__icon--plus:after{content:\"\";position:absolute;left:50%;top:50%;width:100%;height:2px;background:var(--legend-item-color);border-radius:999px;transform:translate(-50%,-50%)}.chart-legend__icon--x:before{transform:translate(-50%,-50%) rotate(45deg)}.chart-legend__icon--x:after{transform:translate(-50%,-50%) rotate(-45deg)}.chart-legend__icon--plus:after{transform:translate(-50%,-50%) rotate(90deg)}.chart-legend__icon--thickLine{height:4px;width:var(--legend-icon-size);border-radius:999px;background:var(--legend-item-color)}.chart-legend__icon--line-marker{display:inline-flex;align-items:center;justify-content:center;padding:0 2px;background:transparent;border:none;min-width:0;width:auto}.chart-legend__icon-line{flex:1 1 1;min-width:8px;height:2px;background:var(--legend-item-color);border-radius:999px}.chart-legend__item--off .chart-legend__icon,.chart-legend__item--off .chart-legend__icon-path path{filter:grayscale(1);opacity:.68}.chart-legend__item--off .chart-legend__icon--emptyCircle,.chart-legend__item--off .chart-legend__icon--emptyRect,.chart-legend__item--off .chart-legend__icon--emptyRoundRect,.chart-legend__item--off .chart-legend__icon--emptySquare,.chart-legend__item--off .chart-legend__icon--emptyDiamond,.chart-legend__item--off .chart-legend__icon--emptyPin,.chart-legend__item--off .chart-legend__icon--emptyLine{filter:grayscale(1);opacity:.68}.chart-legend__content{display:flex;align-items:center;justify-content:space-between;gap:1rem}.chart-legend__value{font-weight:600;font-size:inherit;font-family:inherit}.chart-legend__item--off .chart-legend__icon--emptyTriangle{filter:grayscale(1);opacity:.68}.chart-legend__label{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:inherit;font-family:inherit}.chart-legend__pagination{align-items:center;display:flex;gap:8px;justify-content:flex-end;margin-top:8px}.chart-legend__page{align-items:center;background:transparent;border:1px solid var(--legend-border-color);border-radius:6px;color:inherit;cursor:pointer;display:inline-flex;font:inherit;height:28px;justify-content:center;width:28px}.chart-legend__page:disabled{cursor:default;opacity:.42}.chart-legend__page-count{color:var(--legend-muted-color);font-size:12px}@media (max-width: 640px){.chart-legend__items{padding-bottom:2px}}.chart-legend__action-arrow{width:12px;height:12px;color:var(--legend-muted-color, #9ca3af);flex:0 0 auto}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
449
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: ChartLegendComponent, isStandalone: true, selector: "lib-chart-legend", inputs: { chart: "chart", series: "series", colors: "colors", config: "config", itemTemplate: "itemTemplate" }, outputs: { legendEvent: "legendEvent" }, viewQueries: [{ propertyName: "itemsScroller", first: true, predicate: ["itemsScroller"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "@if (config.enabled !== false) {\r\n <nav\r\n class=\"chart-legend\"\r\n [class.chart-legend--vertical]=\"isVerticalLegend\"\r\n [class.chart-legend--scrollable]=\"isScrollableLegend\"\r\n [class.chart-legend--wrap]=\"!isScrollableLegend\"\r\n [class.chart-legend--limited-wrap]=\"isLimitedWrapLegend\"\r\n [ngClass]=\"config.className || null\"\r\n [style.max-height]=\"config.maxHeight || null\"\r\n [style.padding]=\"config.padding || '1rem'\"\r\n [attr.aria-label]=\"config.ariaLabel || 'Chart legend'\"\r\n >\r\n <div class=\"chart-legend__viewport\">\r\n @if (config.title) {\r\n <p\r\n class=\"chart-legend-title\"\r\n [class.chart-legend-title--uppercase]=\"config.legendTitleTransform === 'uppercase'\"\r\n [class.chart-legend-title--lowercase]=\"config.legendTitleTransform === 'lowercase'\"\r\n [class.chart-legend-title--capitalize]=\"config.legendTitleTransform === 'capitalize'\"\r\n [style.--legend-title-color]=\"config.legendTitleTextColor || null\"\r\n [style.--legend-title-font-size]=\"\r\n config.legendTitleFontSize ? config.legendTitleFontSize + 'px' : null\r\n \"\r\n [style.--legend-title-font-style]=\"config.legendTitleFontStyle || null\"\r\n [style.--legend-title-font-weight]=\"config.legendTitleFontWeight || null\"\r\n [style.--legend-title-text-decoration]=\"config.legendTitleTextDecoration || null\"\r\n [style.--legend-title-font-family]=\"config.legendTitleFontFamily || 'initial'\"\r\n >\r\n {{ config.title }}\r\n </p>\r\n }\r\n @if (usesInternalLegendScroll && canScrollLegend) {\r\n <button\r\n type=\"button\"\r\n class=\"chart-legend__scroll-button chart-legend__scroll-button--start\"\r\n [disabled]=\"!canScrollStart\"\r\n (click)=\"scrollLegend(-1, $event)\"\r\n [attr.aria-label]=\"scrollStartAriaLabel\"\r\n >\r\n <img\r\n src=\"images/legend_left.svg\"\r\n [class.chart-legend__scroll-icon--up]=\"scrollsVertically\"\r\n alt=\"left\"\r\n />\r\n </button>\r\n }\r\n\r\n <div #itemsScroller class=\"chart-legend__scroller\" (scroll)=\"updateScrollState()\">\r\n <div\r\n class=\"chart-legend__items\"\r\n role=\"list\"\r\n [class.chart-legend__items--center]=\"\r\n isLegendAlignedCenter && (!usesInternalLegendScroll || !canScrollLegend)\r\n \"\r\n [class.chart-legend__items--end]=\"isLegendAlignedEnd\"\r\n [style.--legend-text-color]=\"config.legendTextColor || null\"\r\n [style.--legend-font-size]=\"config.legendFontSize ? config.legendFontSize + 'px' : null\"\r\n [style.--legend-font-style]=\"config.legendFontStyle || null\"\r\n [style.--legend-font-weight]=\"config.legendFontWeight || null\"\r\n [style.--legend-text-decoration]=\"config.legendTextDecoration || null\"\r\n [style.--legend-font-family]=\"config.legendFontFamily || 'initial'\"\r\n >\r\n @for (group of groupedItems; track trackByGroup($index, group)) {\r\n @if (group.group) {\r\n <div class=\"chart-legend__group-label\">{{ group.group }}</div>\r\n }\r\n\r\n @for (item of group.items; track trackByItem($index, item)) {\r\n <button\r\n type=\"button\"\r\n class=\"chart-legend__item\"\r\n role=\"switch\"\r\n [class.chart-legend__item--off]=\"!item.selected\"\r\n [class.chart-legend__item--disabled]=\"item.disabled\"\r\n [class.chart-legend__item--hovered]=\"state.hoveredName === item.name\"\r\n [disabled]=\"item.disabled\"\r\n [attr.aria-checked]=\"item.selected\"\r\n [attr.aria-label]=\"item.label\"\r\n [style.--legend-item-color]=\"item.color\"\r\n [title]=\"itemTitle(item)\"\r\n (click)=\"toggle(item, $event)\"\r\n (keydown.enter)=\"toggle(item, $event)\"\r\n (keydown.space)=\"toggle(item, $event)\"\r\n (mouseenter)=\"hover(item)\"\r\n (focus)=\"hover(item)\"\r\n (mouseleave)=\"leave(item)\"\r\n (blur)=\"leave(item)\"\r\n >\r\n @if (templateFor(item); as template) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"template\"\r\n [ngTemplateOutletContext]=\"templateContext(item)\"\r\n ></ng-container>\r\n } @else {\r\n @switch (iconRenderType(item)) {\r\n @case ('image') {\r\n @if (isLineMarker(item)) {\r\n <span\r\n class=\"chart-legend__icon chart-legend__icon--line-marker\"\r\n aria-hidden=\"true\"\r\n >\r\n <span class=\"chart-legend__icon-line\"></span>\r\n <img class=\"chart-legend__icon-image\" [src]=\"iconImageSrc(item)\" alt=\"\" />\r\n <span class=\"chart-legend__icon-line\"></span>\r\n </span>\r\n } @else {\r\n <img class=\"chart-legend__icon-image\" [src]=\"iconImageSrc(item)\" alt=\"\" />\r\n }\r\n }\r\n @case ('path') {\r\n @if (isLineMarker(item)) {\r\n <span\r\n class=\"chart-legend__icon chart-legend__icon--line-marker\"\r\n aria-hidden=\"true\"\r\n >\r\n <span class=\"chart-legend__icon-line\"></span>\r\n <svg\r\n class=\"chart-legend__icon-path\"\r\n viewBox=\"-512 -512 1024 1024\"\r\n aria-hidden=\"true\"\r\n >\r\n <path [attr.d]=\"iconPathData(item)\"></path>\r\n </svg>\r\n <span class=\"chart-legend__icon-line\"></span>\r\n </span>\r\n } @else {\r\n <svg\r\n class=\"chart-legend__icon-path\"\r\n viewBox=\"-512 -512 1024 1024\"\r\n aria-hidden=\"true\"\r\n >\r\n <path [attr.d]=\"iconPathData(item)\"></path>\r\n </svg>\r\n }\r\n }\r\n @case ('shape') {\r\n @if (isLineMarker(item)) {\r\n <span\r\n class=\"chart-legend__icon chart-legend__icon--line-marker\"\r\n aria-hidden=\"true\"\r\n >\r\n <span class=\"chart-legend__icon-line\"></span>\r\n <span\r\n class=\"chart-legend__icon chart-legend__icon--marker\"\r\n [ngClass]=\"iconShapeClass(item.icon)\"\r\n ></span>\r\n <span class=\"chart-legend__icon-line\"></span>\r\n </span>\r\n } @else {\r\n <span\r\n class=\"chart-legend__icon\"\r\n [ngClass]=\"iconShapeClass(iconForRender(item))\"\r\n aria-hidden=\"true\"\r\n ></span>\r\n }\r\n }\r\n }\r\n <span class=\"chart-legend__label\">\n {{ item.label }}@if (this.config.showValue && this.config.valueFormatter) {\n :\n }\n </span>\n @if (this.config.showValue && this.config.valueFormatter) {\r\n <span class=\"chart-legend__value\">{{ this.config.valueFormatter(item) }}</span>\r\n }\r\n @if (this.config.showActionArrow) {\r\n @if (this.config.actionArrowTemplate) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"this.config.actionArrowTemplate\"\r\n [ngTemplateOutletContext]=\"templateContext(item)\"\r\n ></ng-container>\r\n } @else {\r\n <svg\r\n class=\"chart-legend__action-arrow\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n >\r\n <polyline points=\"9 18 15 12 9 6\"></polyline>\r\n </svg>\r\n }\r\n }\r\n }\r\n </button>\r\n }\r\n }\r\n </div>\r\n </div>\r\n\r\n @if (usesInternalLegendScroll && canScrollLegend) {\r\n <button\r\n type=\"button\"\r\n class=\"chart-legend__scroll-button chart-legend__scroll-button--end\"\r\n [disabled]=\"!canScrollEnd\"\r\n (click)=\"scrollLegend(1, $event)\"\r\n [attr.aria-label]=\"scrollEndAriaLabel\"\r\n >\r\n <img\r\n src=\"images/legend_right.svg\"\r\n [class.chart-legend__scroll-icon--down]=\"scrollsVertically\"\r\n alt=\"right\"\r\n />\r\n </button>\r\n }\r\n </div>\r\n\r\n @if (config.showPagination && pageCount > 1) {\r\n <div class=\"chart-legend__pagination\" aria-label=\"Legend pages\">\r\n <button\r\n type=\"button\"\r\n class=\"chart-legend__page\"\r\n [disabled]=\"state.pageIndex === 0\"\r\n (click)=\"page(-1)\"\r\n aria-label=\"Previous legend page\"\r\n >\r\n <\r\n </button>\r\n <span class=\"chart-legend__page-count\">{{ state.pageIndex + 1 }} / {{ pageCount }}</span>\r\n <button\r\n type=\"button\"\r\n class=\"chart-legend__page\"\r\n [disabled]=\"state.pageIndex + 1 === pageCount\"\r\n (click)=\"page(1)\"\r\n aria-label=\"Next legend page\"\r\n >\r\n >\r\n </button>\r\n </div>\r\n }\r\n </nav>\r\n}\r\n", styles: [":host{display:block;min-height:0;min-width:0}.chart-legend{--legend-text-color: #040d17;--legend-muted-color: #8a94a6;--legend-border-color: #eaf3fd;--legend-hover-bg: rgba(15, 23, 42, .04);--legend-font-size: 14px;--legend-item-min-height: 28px;--legend-row-gap: 8px;--legend-column-gap: 12px;--legend-font-style: normal;--legend-font-weight: 400;--legend-text-decoration: none;--legend-font-family: initial;--legend-title-color: #040d17;--legend-title-font-size: 14px;--legend-title-font-style: normal;--legend-title-font-weight: 400;--legend-title-text-decoration: none;--legend-title-font-family: initial;box-sizing:border-box;min-height:0;min-width:0;width:100%}:host-context(.dark) .chart-legend,:host-context([data-theme=dark]) .chart-legend{--legend-text-color: #e5e7eb;--legend-muted-color: #9ca3af;--legend-border-color: #374151;--legend-hover-bg: rgba(255, 255, 255, .08)}.chart-legend__viewport{align-items:center;display:flex;gap:4px;min-width:0;width:100%}.chart-legend__viewport .chart-legend-title{font-weight:var(--legend-title-font-weight);font-size:var(--legend-title-font-size);font-style:var(--legend-title-font-style);text-decoration:var(--legend-title-text-decoration);font-family:var(--legend-title-font-family);color:var(--legend-title-color);white-space:nowrap;margin:0 8px 0 0}.chart-legend__viewport .chart-legend-title--uppercase{text-transform:uppercase}.chart-legend__viewport .chart-legend-title--lowercase{text-transform:lowercase}.chart-legend__viewport .chart-legend-title--capitalize{text-transform:capitalize}.chart-legend__scroller{flex:1 1 auto;min-height:0;min-width:0;overflow-x:hidden;overflow-y:hidden;scrollbar-width:none}.chart-legend__scroller::-webkit-scrollbar{display:none}.chart-legend--scrollable .chart-legend__scroller{overflow-x:auto;overscroll-behavior-x:contain}.chart-legend--scrollable .chart-legend__scroller::-webkit-scrollbar{display:block;height:6px}.chart-legend__items{display:flex;flex-wrap:nowrap;align-items:center;gap:var(--legend-row-gap) var(--legend-column-gap);min-width:0;color:var(--legend-text-color);font-size:var(--legend-font-size);font-style:var(--legend-font-style);font-weight:var(--legend-font-weight);text-decoration:var(--legend-text-decoration);font-family:var(--legend-font-family)}.chart-legend--scrollable .chart-legend__items{min-width:max-content}.chart-legend--wrap:not(.chart-legend--vertical) .chart-legend__items{flex-wrap:wrap;width:100%}.chart-legend--limited-wrap:not(.chart-legend--vertical) .chart-legend__scroller{max-height:calc(var(--legend-item-min-height) * 2 + var(--legend-row-gap));overflow-y:auto;overscroll-behavior-y:contain}.chart-legend--vertical{height:100%}.chart-legend--vertical .chart-legend__viewport{align-items:stretch;flex-direction:column;height:100%;min-height:0}.chart-legend--vertical .chart-legend__scroller{overflow-x:hidden;overflow-y:hidden}.chart-legend--vertical.chart-legend--scrollable .chart-legend__scroller{overflow-y:auto;overscroll-behavior-y:contain}.chart-legend--vertical .chart-legend__items{align-items:stretch;flex-direction:column;min-width:0;width:100%;height:100%}.chart-legend--vertical.chart-legend--wrap .chart-legend__items{align-content:start;display:grid;grid-auto-flow:column;grid-auto-columns:max-content;grid-template-rows:repeat(auto-fit,minmax(28px,max-content));height:100%;justify-content:start;width:auto}.chart-legend--vertical.chart-legend--limited-wrap .chart-legend__viewport{flex-direction:row}.chart-legend--vertical.chart-legend--limited-wrap .chart-legend__scroller{overflow-x:auto;overflow-y:hidden;overscroll-behavior-x:contain}.chart-legend--vertical.chart-legend--limited-wrap .chart-legend__items{grid-auto-columns:minmax(1,calc((100% - var(--legend-column-gap)) / 2));width:max-content}.chart-legend__items--center{justify-content:center}.chart-legend__items--end{justify-content:flex-end}.chart-legend--vertical.chart-legend--wrap .chart-legend__items--center{align-content:center;justify-content:start}.chart-legend--vertical.chart-legend--wrap .chart-legend__items--end{align-content:end;justify-content:start}.chart-legend__group-label{flex:0 0 auto;color:var(--legend-muted-color);font-size:12px;font-weight:600;line-height:1.2;margin-top:4px}.chart-legend__item{--legend-item-color: #64748b;align-items:center;background:color-mix(in srgb,var(--legend-item-color) 4%,transparent);border:1px solid color-mix(in srgb,var(--legend-item-color) 25%,transparent);border-radius:4px;color:inherit;cursor:pointer;display:inline-flex;font:inherit;gap:8px;line-height:1.2;min-height:28px;min-width:0;padding:4px 8px;touch-action:manipulation;transition:background-color .14s ease,border-color .14s ease,opacity .14s ease}.chart-legend--vertical .chart-legend__item{justify-content:flex-start;width:100%}.chart-legend--vertical.chart-legend--wrap .chart-legend__item{width:auto}.chart-legend--vertical.chart-legend--limited-wrap .chart-legend__item{width:100%}.chart-legend__scroll-button{align-items:center;background:transparent;border:1px solid var(--legend-border-color);border-radius:6px;color:inherit;cursor:pointer;display:inline-flex;flex:0 0 auto;font:inherit;height:28px;justify-content:center;line-height:1;width:28px}.chart-legend--vertical .chart-legend__scroll-button{width:100%}.chart-legend--vertical.chart-legend--limited-wrap .chart-legend__scroll-button{height:auto;min-height:28px;width:28px}.chart-legend__scroll-button img{display:block;height:10px;width:10px}.chart-legend__scroll-icon--up,.chart-legend__scroll-icon--down{transform:rotate(90deg)}.chart-legend__scroll-button:disabled{cursor:default;opacity:.42}.chart-legend__item:hover,.chart-legend__item:focus-visible,.chart-legend__item--hovered{outline:none}.chart-legend__item--off{color:var(--legend-muted-color);filter:grayscale(1);opacity:.68}.chart-legend__item--disabled{cursor:not-allowed;opacity:.48}.chart-legend__icon,.chart-legend__icon-image,.chart-legend__icon-path{--legend-icon-size: 12px;background:var(--legend-item-color);box-sizing:border-box;display:inline-block;flex:0 0 auto;height:var(--legend-icon-size);width:var(--legend-icon-size)}.chart-legend__icon-image,.chart-legend__icon-path{background:transparent;object-fit:contain}.chart-legend__icon-path path{fill:var(--legend-item-color);stroke:var(--legend-item-color)}.chart-legend__icon--line,.chart-legend__icon--emptyLine{height:11px;border-radius:999px;background:linear-gradient(to bottom,transparent 0 4px,var(--legend-item-color) 4px 6px,transparent 6px 100%)}.chart-legend__icon--emptyLine{background:linear-gradient(to bottom,transparent 0 4px,var(--legend-item-color) 4px 6px,transparent 6px 100%)}.chart-legend__icon--area{background:linear-gradient(to bottom,var(--legend-item-color),color-mix(in srgb,var(--legend-item-color) 12%,transparent));border-top:3px solid var(--legend-item-color)}.chart-legend__icon--circle{border-radius:50%}.chart-legend__icon--emptyCircle{background:transparent;border:2px solid var(--legend-item-color);border-radius:50%}.chart-legend__icon--rect,.chart-legend__icon--emptyRect,.chart-legend__icon--square,.chart-legend__icon--emptySquare{border-radius:2px}.chart-legend__icon--emptyRect,.chart-legend__icon--emptySquare{background:transparent;border:2px solid var(--legend-item-color)}.chart-legend__icon--roundRect,.chart-legend__icon--emptyRoundRect{border-radius:6px}.chart-legend__icon--emptyRoundRect{background:transparent;border:2px solid var(--legend-item-color)}.chart-legend__icon--triangle,.chart-legend__icon--emptyTriangle{clip-path:polygon(50% 0,100% 100%,0 100%)}.chart-legend__icon--emptyTriangle{background:var(--legend-item-color)}.chart-legend__icon--diamond,.chart-legend__icon--emptyDiamond{transform:rotate(45deg)}.chart-legend__icon--emptyDiamond{background:transparent;border:2px solid var(--legend-item-color)}.chart-legend__icon--pin,.chart-legend__icon--emptyPin{border-radius:50% 50% 50% 0;transform:rotate(-45deg)}.chart-legend__icon--emptyPin{background:transparent;border:2px solid var(--legend-item-color)}.chart-legend__icon--arrow,.chart-legend__icon--emptyArrow{clip-path:polygon(0 35%,58% 35%,58% 10%,100% 50%,58% 90%,58% 65%,0 65%)}.chart-legend__icon--emptyArrow{opacity:.72}.chart-legend__icon--x,.chart-legend__icon--plus,.chart-legend__icon--thickLine{background:transparent;position:relative}.chart-legend__icon--x:before,.chart-legend__icon--x:after,.chart-legend__icon--plus:before,.chart-legend__icon--plus:after{content:\"\";position:absolute;left:50%;top:50%;width:100%;height:2px;background:var(--legend-item-color);border-radius:999px;transform:translate(-50%,-50%)}.chart-legend__icon--x:before{transform:translate(-50%,-50%) rotate(45deg)}.chart-legend__icon--x:after{transform:translate(-50%,-50%) rotate(-45deg)}.chart-legend__icon--plus:after{transform:translate(-50%,-50%) rotate(90deg)}.chart-legend__icon--thickLine{height:4px;width:var(--legend-icon-size);border-radius:999px;background:var(--legend-item-color)}.chart-legend__icon--line-marker{display:inline-flex;align-items:center;justify-content:center;padding:0 2px;background:transparent;border:none;min-width:0;width:auto}.chart-legend__icon-line{flex:1 1 1;min-width:8px;height:2px;background:var(--legend-item-color);border-radius:999px}.chart-legend__item--off .chart-legend__icon,.chart-legend__item--off .chart-legend__icon-path path{filter:grayscale(1);opacity:.68}.chart-legend__item--off .chart-legend__icon--emptyCircle,.chart-legend__item--off .chart-legend__icon--emptyRect,.chart-legend__item--off .chart-legend__icon--emptyRoundRect,.chart-legend__item--off .chart-legend__icon--emptySquare,.chart-legend__item--off .chart-legend__icon--emptyDiamond,.chart-legend__item--off .chart-legend__icon--emptyPin,.chart-legend__item--off .chart-legend__icon--emptyLine{filter:grayscale(1);opacity:.68}.chart-legend__content{display:flex;align-items:center;justify-content:space-between;gap:1rem}.chart-legend__value{font-weight:600;font-size:inherit;font-family:inherit}.chart-legend__item--off .chart-legend__icon--emptyTriangle{filter:grayscale(1);opacity:.68}.chart-legend__label{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:inherit;font-family:inherit}.chart-legend__pagination{align-items:center;display:flex;gap:8px;justify-content:flex-end;margin-top:8px}.chart-legend__page{align-items:center;background:transparent;border:1px solid var(--legend-border-color);border-radius:6px;color:inherit;cursor:pointer;display:inline-flex;font:inherit;height:28px;justify-content:center;width:28px}.chart-legend__page:disabled{cursor:default;opacity:.42}.chart-legend__page-count{color:var(--legend-muted-color);font-size:12px}@media (max-width: 640px){.chart-legend__items{padding-bottom:2px}}.chart-legend__action-arrow{width:12px;height:12px;color:var(--legend-muted-color, #9ca3af);flex:0 0 auto}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
450
450
|
}
|
|
451
451
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ChartLegendComponent, decorators: [{
|
|
452
452
|
type: Component,
|
|
453
|
-
args: [{ selector: 'lib-chart-legend', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (config.enabled !== false) {\r\n <nav\r\n class=\"chart-legend\"\r\n [class.chart-legend--vertical]=\"isVerticalLegend\"\r\n [class.chart-legend--scrollable]=\"isScrollableLegend\"\r\n [class.chart-legend--wrap]=\"!isScrollableLegend\"\r\n [class.chart-legend--limited-wrap]=\"isLimitedWrapLegend\"\r\n [ngClass]=\"config.className || null\"\r\n [style.max-height]=\"config.maxHeight || null\"\r\n [style.padding]=\"config.padding || '1rem'\"\r\n [attr.aria-label]=\"config.ariaLabel || 'Chart legend'\"\r\n >\r\n <div class=\"chart-legend__viewport\">\r\n @if (config.title) {\r\n <p\r\n class=\"chart-legend-title\"\r\n [class.chart-legend-title--uppercase]=\"config.legendTitleTransform === 'uppercase'\"\r\n [class.chart-legend-title--lowercase]=\"config.legendTitleTransform === 'lowercase'\"\r\n [class.chart-legend-title--capitalize]=\"config.legendTitleTransform === 'capitalize'\"\r\n [style.--legend-title-color]=\"config.legendTitleTextColor || null\"\r\n [style.--legend-title-font-size]=\"\r\n config.legendTitleFontSize ? config.legendTitleFontSize + 'px' : null\r\n \"\r\n [style.--legend-title-font-style]=\"config.legendTitleFontStyle || null\"\r\n [style.--legend-title-font-weight]=\"config.legendTitleFontWeight || null\"\r\n [style.--legend-title-text-decoration]=\"config.legendTitleTextDecoration || null\"\r\n [style.--legend-title-font-family]=\"config.legendTitleFontFamily || 'initial'\"\r\n >\r\n {{ config.title }}\r\n </p>\r\n }\r\n @if (usesInternalLegendScroll && canScrollLegend) {\r\n <button\r\n type=\"button\"\r\n class=\"chart-legend__scroll-button chart-legend__scroll-button--start\"\r\n [disabled]=\"!canScrollStart\"\r\n (click)=\"scrollLegend(-1, $event)\"\r\n [attr.aria-label]=\"scrollStartAriaLabel\"\r\n >\r\n <img\r\n src=\"images/legend_left.svg\"\r\n [class.chart-legend__scroll-icon--up]=\"scrollsVertically\"\r\n alt=\"left\"\r\n />\r\n </button>\r\n }\r\n\r\n <div #itemsScroller class=\"chart-legend__scroller\" (scroll)=\"updateScrollState()\">\r\n <div\r\n class=\"chart-legend__items\"\r\n role=\"list\"\r\n [class.chart-legend__items--center]=\"\r\n isLegendAlignedCenter && (!usesInternalLegendScroll || !canScrollLegend)\r\n \"\r\n [class.chart-legend__items--end]=\"isLegendAlignedEnd\"\r\n [style.--legend-text-color]=\"config.legendTextColor || null\"\r\n [style.--legend-font-size]=\"config.legendFontSize ? config.legendFontSize + 'px' : null\"\r\n [style.--legend-font-style]=\"config.legendFontStyle || null\"\r\n [style.--legend-font-weight]=\"config.legendFontWeight || null\"\r\n [style.--legend-text-decoration]=\"config.legendTextDecoration || null\"\r\n [style.--legend-font-family]=\"config.legendFontFamily || 'initial'\"\r\n >\r\n @for (group of groupedItems; track trackByGroup($index, group)) {\r\n @if (group.group) {\r\n <div class=\"chart-legend__group-label\">{{ group.group }}</div>\r\n }\r\n\r\n @for (item of group.items; track trackByItem($index, item)) {\r\n <button\r\n type=\"button\"\r\n class=\"chart-legend__item\"\r\n role=\"switch\"\r\n [class.chart-legend__item--off]=\"!item.selected\"\r\n [class.chart-legend__item--disabled]=\"item.disabled\"\r\n [class.chart-legend__item--hovered]=\"state.hoveredName === item.name\"\r\n [disabled]=\"item.disabled\"\r\n [attr.aria-checked]=\"item.selected\"\r\n [attr.aria-label]=\"item.label\"\r\n [style.--legend-item-color]=\"item.color\"\r\n [title]=\"itemTitle(item)\"\r\n (click)=\"toggle(item, $event)\"\r\n (keydown.enter)=\"toggle(item, $event)\"\r\n (keydown.space)=\"toggle(item, $event)\"\r\n (mouseenter)=\"hover(item)\"\r\n (focus)=\"hover(item)\"\r\n (mouseleave)=\"leave(item)\"\r\n (blur)=\"leave(item)\"\r\n >\r\n @if (templateFor(item); as template) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"template\"\r\n [ngTemplateOutletContext]=\"templateContext(item)\"\r\n ></ng-container>\r\n } @else {\r\n @switch (iconRenderType(item)) {\r\n @case ('image') {\r\n @if (isLineMarker(item)) {\r\n <span\r\n class=\"chart-legend__icon chart-legend__icon--line-marker\"\r\n aria-hidden=\"true\"\r\n >\r\n <span class=\"chart-legend__icon-line\"></span>\r\n <img class=\"chart-legend__icon-image\" [src]=\"iconImageSrc(item)\" alt=\"\" />\r\n <span class=\"chart-legend__icon-line\"></span>\r\n </span>\r\n } @else {\r\n <img class=\"chart-legend__icon-image\" [src]=\"iconImageSrc(item)\" alt=\"\" />\r\n }\r\n }\r\n @case ('path') {\r\n @if (isLineMarker(item)) {\r\n <span\r\n class=\"chart-legend__icon chart-legend__icon--line-marker\"\r\n aria-hidden=\"true\"\r\n >\r\n <span class=\"chart-legend__icon-line\"></span>\r\n <svg\r\n class=\"chart-legend__icon-path\"\r\n viewBox=\"-512 -512 1024 1024\"\r\n aria-hidden=\"true\"\r\n >\r\n <path [attr.d]=\"iconPathData(item)\"></path>\r\n </svg>\r\n <span class=\"chart-legend__icon-line\"></span>\r\n </span>\r\n } @else {\r\n <svg\r\n class=\"chart-legend__icon-path\"\r\n viewBox=\"-512 -512 1024 1024\"\r\n aria-hidden=\"true\"\r\n >\r\n <path [attr.d]=\"iconPathData(item)\"></path>\r\n </svg>\r\n }\r\n }\r\n @case ('shape') {\r\n @if (isLineMarker(item)) {\r\n <span\r\n class=\"chart-legend__icon chart-legend__icon--line-marker\"\r\n aria-hidden=\"true\"\r\n >\r\n <span class=\"chart-legend__icon-line\"></span>\r\n <span\r\n class=\"chart-legend__icon chart-legend__icon--marker\"\r\n [ngClass]=\"iconShapeClass(item.icon)\"\r\n ></span>\r\n <span class=\"chart-legend__icon-line\"></span>\r\n </span>\r\n } @else {\r\n <span\r\n class=\"chart-legend__icon\"\r\n [ngClass]=\"iconShapeClass(iconForRender(item))\"\r\n aria-hidden=\"true\"\r\n ></span>\r\n }\r\n }\r\n }\r\n <span class=\"chart-legend__label\"\r\n >{{ item.label\r\n }}{{ this.config.showValue && this.config.valueFormatter && ':' }}</span\r\n >\r\n @if (this.config.showValue && this.config.valueFormatter) {\r\n <span class=\"chart-legend__value\">{{ this.config.valueFormatter(item) }}</span>\r\n }\r\n @if (this.config.showActionArrow) {\r\n @if (this.config.actionArrowTemplate) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"this.config.actionArrowTemplate\"\r\n [ngTemplateOutletContext]=\"templateContext(item)\"\r\n ></ng-container>\r\n } @else {\r\n <svg\r\n class=\"chart-legend__action-arrow\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n >\r\n <polyline points=\"9 18 15 12 9 6\"></polyline>\r\n </svg>\r\n }\r\n }\r\n }\r\n </button>\r\n }\r\n }\r\n </div>\r\n </div>\r\n\r\n @if (usesInternalLegendScroll && canScrollLegend) {\r\n <button\r\n type=\"button\"\r\n class=\"chart-legend__scroll-button chart-legend__scroll-button--end\"\r\n [disabled]=\"!canScrollEnd\"\r\n (click)=\"scrollLegend(1, $event)\"\r\n [attr.aria-label]=\"scrollEndAriaLabel\"\r\n >\r\n <img\r\n src=\"images/legend_right.svg\"\r\n [class.chart-legend__scroll-icon--down]=\"scrollsVertically\"\r\n alt=\"right\"\r\n />\r\n </button>\r\n }\r\n </div>\r\n\r\n @if (config.showPagination && pageCount > 1) {\r\n <div class=\"chart-legend__pagination\" aria-label=\"Legend pages\">\r\n <button\r\n type=\"button\"\r\n class=\"chart-legend__page\"\r\n [disabled]=\"state.pageIndex === 0\"\r\n (click)=\"page(-1)\"\r\n aria-label=\"Previous legend page\"\r\n >\r\n <\r\n </button>\r\n <span class=\"chart-legend__page-count\">{{ state.pageIndex + 1 }} / {{ pageCount }}</span>\r\n <button\r\n type=\"button\"\r\n class=\"chart-legend__page\"\r\n [disabled]=\"state.pageIndex + 1 === pageCount\"\r\n (click)=\"page(1)\"\r\n aria-label=\"Next legend page\"\r\n >\r\n >\r\n </button>\r\n </div>\r\n }\r\n </nav>\r\n}\r\n", styles: [":host{display:block;min-height:0;min-width:0}.chart-legend{--legend-text-color: #040d17;--legend-muted-color: #8a94a6;--legend-border-color: #eaf3fd;--legend-hover-bg: rgba(15, 23, 42, .04);--legend-font-size: 14px;--legend-item-min-height: 28px;--legend-row-gap: 8px;--legend-column-gap: 12px;--legend-font-style: normal;--legend-font-weight: 400;--legend-text-decoration: none;--legend-font-family: initial;--legend-title-color: #040d17;--legend-title-font-size: 14px;--legend-title-font-style: normal;--legend-title-font-weight: 400;--legend-title-text-decoration: none;--legend-title-font-family: initial;box-sizing:border-box;min-height:0;min-width:0;width:100%}:host-context(.dark) .chart-legend,:host-context([data-theme=dark]) .chart-legend{--legend-text-color: #e5e7eb;--legend-muted-color: #9ca3af;--legend-border-color: #374151;--legend-hover-bg: rgba(255, 255, 255, .08)}.chart-legend__viewport{align-items:center;display:flex;gap:4px;min-width:0;width:100%}.chart-legend__viewport .chart-legend-title{font-weight:var(--legend-title-font-weight);font-size:var(--legend-title-font-size);font-style:var(--legend-title-font-style);text-decoration:var(--legend-title-text-decoration);font-family:var(--legend-title-font-family);color:var(--legend-title-color);white-space:nowrap;margin:0 8px 0 0}.chart-legend__viewport .chart-legend-title--uppercase{text-transform:uppercase}.chart-legend__viewport .chart-legend-title--lowercase{text-transform:lowercase}.chart-legend__viewport .chart-legend-title--capitalize{text-transform:capitalize}.chart-legend__scroller{flex:1 1 auto;min-height:0;min-width:0;overflow-x:hidden;overflow-y:hidden;scrollbar-width:none}.chart-legend__scroller::-webkit-scrollbar{display:none}.chart-legend--scrollable .chart-legend__scroller{overflow-x:auto;overscroll-behavior-x:contain}.chart-legend--scrollable .chart-legend__scroller::-webkit-scrollbar{display:block;height:6px}.chart-legend__items{display:flex;flex-wrap:nowrap;align-items:center;gap:var(--legend-row-gap) var(--legend-column-gap);min-width:0;color:var(--legend-text-color);font-size:var(--legend-font-size);font-style:var(--legend-font-style);font-weight:var(--legend-font-weight);text-decoration:var(--legend-text-decoration);font-family:var(--legend-font-family)}.chart-legend--scrollable .chart-legend__items{min-width:max-content}.chart-legend--wrap:not(.chart-legend--vertical) .chart-legend__items{flex-wrap:wrap;width:100%}.chart-legend--limited-wrap:not(.chart-legend--vertical) .chart-legend__scroller{max-height:calc(var(--legend-item-min-height) * 2 + var(--legend-row-gap));overflow-y:auto;overscroll-behavior-y:contain}.chart-legend--vertical{height:100%}.chart-legend--vertical .chart-legend__viewport{align-items:stretch;flex-direction:column;height:100%;min-height:0}.chart-legend--vertical .chart-legend__scroller{overflow-x:hidden;overflow-y:hidden}.chart-legend--vertical.chart-legend--scrollable .chart-legend__scroller{overflow-y:auto;overscroll-behavior-y:contain}.chart-legend--vertical .chart-legend__items{align-items:stretch;flex-direction:column;min-width:0;width:100%;height:100%}.chart-legend--vertical.chart-legend--wrap .chart-legend__items{align-content:start;display:grid;grid-auto-flow:column;grid-auto-columns:max-content;grid-template-rows:repeat(auto-fit,minmax(28px,max-content));height:100%;justify-content:start;width:auto}.chart-legend--vertical.chart-legend--limited-wrap .chart-legend__viewport{flex-direction:row}.chart-legend--vertical.chart-legend--limited-wrap .chart-legend__scroller{overflow-x:auto;overflow-y:hidden;overscroll-behavior-x:contain}.chart-legend--vertical.chart-legend--limited-wrap .chart-legend__items{grid-auto-columns:minmax(1,calc((100% - var(--legend-column-gap)) / 2));width:max-content}.chart-legend__items--center{justify-content:center}.chart-legend__items--end{justify-content:flex-end}.chart-legend--vertical.chart-legend--wrap .chart-legend__items--center{align-content:center;justify-content:start}.chart-legend--vertical.chart-legend--wrap .chart-legend__items--end{align-content:end;justify-content:start}.chart-legend__group-label{flex:0 0 auto;color:var(--legend-muted-color);font-size:12px;font-weight:600;line-height:1.2;margin-top:4px}.chart-legend__item{--legend-item-color: #64748b;align-items:center;background:color-mix(in srgb,var(--legend-item-color) 4%,transparent);border:1px solid color-mix(in srgb,var(--legend-item-color) 25%,transparent);border-radius:4px;color:inherit;cursor:pointer;display:inline-flex;font:inherit;gap:8px;line-height:1.2;min-height:28px;min-width:0;padding:4px 8px;touch-action:manipulation;transition:background-color .14s ease,border-color .14s ease,opacity .14s ease}.chart-legend--vertical .chart-legend__item{justify-content:flex-start;width:100%}.chart-legend--vertical.chart-legend--wrap .chart-legend__item{width:auto}.chart-legend--vertical.chart-legend--limited-wrap .chart-legend__item{width:100%}.chart-legend__scroll-button{align-items:center;background:transparent;border:1px solid var(--legend-border-color);border-radius:6px;color:inherit;cursor:pointer;display:inline-flex;flex:0 0 auto;font:inherit;height:28px;justify-content:center;line-height:1;width:28px}.chart-legend--vertical .chart-legend__scroll-button{width:100%}.chart-legend--vertical.chart-legend--limited-wrap .chart-legend__scroll-button{height:auto;min-height:28px;width:28px}.chart-legend__scroll-button img{display:block;height:10px;width:10px}.chart-legend__scroll-icon--up,.chart-legend__scroll-icon--down{transform:rotate(90deg)}.chart-legend__scroll-button:disabled{cursor:default;opacity:.42}.chart-legend__item:hover,.chart-legend__item:focus-visible,.chart-legend__item--hovered{outline:none}.chart-legend__item--off{color:var(--legend-muted-color);filter:grayscale(1);opacity:.68}.chart-legend__item--disabled{cursor:not-allowed;opacity:.48}.chart-legend__icon,.chart-legend__icon-image,.chart-legend__icon-path{--legend-icon-size: 12px;background:var(--legend-item-color);box-sizing:border-box;display:inline-block;flex:0 0 auto;height:var(--legend-icon-size);width:var(--legend-icon-size)}.chart-legend__icon-image,.chart-legend__icon-path{background:transparent;object-fit:contain}.chart-legend__icon-path path{fill:var(--legend-item-color);stroke:var(--legend-item-color)}.chart-legend__icon--line,.chart-legend__icon--emptyLine{height:11px;border-radius:999px;background:linear-gradient(to bottom,transparent 0 4px,var(--legend-item-color) 4px 6px,transparent 6px 100%)}.chart-legend__icon--emptyLine{background:linear-gradient(to bottom,transparent 0 4px,var(--legend-item-color) 4px 6px,transparent 6px 100%)}.chart-legend__icon--area{background:linear-gradient(to bottom,var(--legend-item-color),color-mix(in srgb,var(--legend-item-color) 12%,transparent));border-top:3px solid var(--legend-item-color)}.chart-legend__icon--circle{border-radius:50%}.chart-legend__icon--emptyCircle{background:transparent;border:2px solid var(--legend-item-color);border-radius:50%}.chart-legend__icon--rect,.chart-legend__icon--emptyRect,.chart-legend__icon--square,.chart-legend__icon--emptySquare{border-radius:2px}.chart-legend__icon--emptyRect,.chart-legend__icon--emptySquare{background:transparent;border:2px solid var(--legend-item-color)}.chart-legend__icon--roundRect,.chart-legend__icon--emptyRoundRect{border-radius:6px}.chart-legend__icon--emptyRoundRect{background:transparent;border:2px solid var(--legend-item-color)}.chart-legend__icon--triangle,.chart-legend__icon--emptyTriangle{clip-path:polygon(50% 0,100% 100%,0 100%)}.chart-legend__icon--emptyTriangle{background:var(--legend-item-color)}.chart-legend__icon--diamond,.chart-legend__icon--emptyDiamond{transform:rotate(45deg)}.chart-legend__icon--emptyDiamond{background:transparent;border:2px solid var(--legend-item-color)}.chart-legend__icon--pin,.chart-legend__icon--emptyPin{border-radius:50% 50% 50% 0;transform:rotate(-45deg)}.chart-legend__icon--emptyPin{background:transparent;border:2px solid var(--legend-item-color)}.chart-legend__icon--arrow,.chart-legend__icon--emptyArrow{clip-path:polygon(0 35%,58% 35%,58% 10%,100% 50%,58% 90%,58% 65%,0 65%)}.chart-legend__icon--emptyArrow{opacity:.72}.chart-legend__icon--x,.chart-legend__icon--plus,.chart-legend__icon--thickLine{background:transparent;position:relative}.chart-legend__icon--x:before,.chart-legend__icon--x:after,.chart-legend__icon--plus:before,.chart-legend__icon--plus:after{content:\"\";position:absolute;left:50%;top:50%;width:100%;height:2px;background:var(--legend-item-color);border-radius:999px;transform:translate(-50%,-50%)}.chart-legend__icon--x:before{transform:translate(-50%,-50%) rotate(45deg)}.chart-legend__icon--x:after{transform:translate(-50%,-50%) rotate(-45deg)}.chart-legend__icon--plus:after{transform:translate(-50%,-50%) rotate(90deg)}.chart-legend__icon--thickLine{height:4px;width:var(--legend-icon-size);border-radius:999px;background:var(--legend-item-color)}.chart-legend__icon--line-marker{display:inline-flex;align-items:center;justify-content:center;padding:0 2px;background:transparent;border:none;min-width:0;width:auto}.chart-legend__icon-line{flex:1 1 1;min-width:8px;height:2px;background:var(--legend-item-color);border-radius:999px}.chart-legend__item--off .chart-legend__icon,.chart-legend__item--off .chart-legend__icon-path path{filter:grayscale(1);opacity:.68}.chart-legend__item--off .chart-legend__icon--emptyCircle,.chart-legend__item--off .chart-legend__icon--emptyRect,.chart-legend__item--off .chart-legend__icon--emptyRoundRect,.chart-legend__item--off .chart-legend__icon--emptySquare,.chart-legend__item--off .chart-legend__icon--emptyDiamond,.chart-legend__item--off .chart-legend__icon--emptyPin,.chart-legend__item--off .chart-legend__icon--emptyLine{filter:grayscale(1);opacity:.68}.chart-legend__content{display:flex;align-items:center;justify-content:space-between;gap:1rem}.chart-legend__value{font-weight:600;font-size:inherit;font-family:inherit}.chart-legend__item--off .chart-legend__icon--emptyTriangle{filter:grayscale(1);opacity:.68}.chart-legend__label{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:inherit;font-family:inherit}.chart-legend__pagination{align-items:center;display:flex;gap:8px;justify-content:flex-end;margin-top:8px}.chart-legend__page{align-items:center;background:transparent;border:1px solid var(--legend-border-color);border-radius:6px;color:inherit;cursor:pointer;display:inline-flex;font:inherit;height:28px;justify-content:center;width:28px}.chart-legend__page:disabled{cursor:default;opacity:.42}.chart-legend__page-count{color:var(--legend-muted-color);font-size:12px}@media (max-width: 640px){.chart-legend__items{padding-bottom:2px}}.chart-legend__action-arrow{width:12px;height:12px;color:var(--legend-muted-color, #9ca3af);flex:0 0 auto}\n"] }]
|
|
453
|
+
args: [{ selector: 'lib-chart-legend', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (config.enabled !== false) {\r\n <nav\r\n class=\"chart-legend\"\r\n [class.chart-legend--vertical]=\"isVerticalLegend\"\r\n [class.chart-legend--scrollable]=\"isScrollableLegend\"\r\n [class.chart-legend--wrap]=\"!isScrollableLegend\"\r\n [class.chart-legend--limited-wrap]=\"isLimitedWrapLegend\"\r\n [ngClass]=\"config.className || null\"\r\n [style.max-height]=\"config.maxHeight || null\"\r\n [style.padding]=\"config.padding || '1rem'\"\r\n [attr.aria-label]=\"config.ariaLabel || 'Chart legend'\"\r\n >\r\n <div class=\"chart-legend__viewport\">\r\n @if (config.title) {\r\n <p\r\n class=\"chart-legend-title\"\r\n [class.chart-legend-title--uppercase]=\"config.legendTitleTransform === 'uppercase'\"\r\n [class.chart-legend-title--lowercase]=\"config.legendTitleTransform === 'lowercase'\"\r\n [class.chart-legend-title--capitalize]=\"config.legendTitleTransform === 'capitalize'\"\r\n [style.--legend-title-color]=\"config.legendTitleTextColor || null\"\r\n [style.--legend-title-font-size]=\"\r\n config.legendTitleFontSize ? config.legendTitleFontSize + 'px' : null\r\n \"\r\n [style.--legend-title-font-style]=\"config.legendTitleFontStyle || null\"\r\n [style.--legend-title-font-weight]=\"config.legendTitleFontWeight || null\"\r\n [style.--legend-title-text-decoration]=\"config.legendTitleTextDecoration || null\"\r\n [style.--legend-title-font-family]=\"config.legendTitleFontFamily || 'initial'\"\r\n >\r\n {{ config.title }}\r\n </p>\r\n }\r\n @if (usesInternalLegendScroll && canScrollLegend) {\r\n <button\r\n type=\"button\"\r\n class=\"chart-legend__scroll-button chart-legend__scroll-button--start\"\r\n [disabled]=\"!canScrollStart\"\r\n (click)=\"scrollLegend(-1, $event)\"\r\n [attr.aria-label]=\"scrollStartAriaLabel\"\r\n >\r\n <img\r\n src=\"images/legend_left.svg\"\r\n [class.chart-legend__scroll-icon--up]=\"scrollsVertically\"\r\n alt=\"left\"\r\n />\r\n </button>\r\n }\r\n\r\n <div #itemsScroller class=\"chart-legend__scroller\" (scroll)=\"updateScrollState()\">\r\n <div\r\n class=\"chart-legend__items\"\r\n role=\"list\"\r\n [class.chart-legend__items--center]=\"\r\n isLegendAlignedCenter && (!usesInternalLegendScroll || !canScrollLegend)\r\n \"\r\n [class.chart-legend__items--end]=\"isLegendAlignedEnd\"\r\n [style.--legend-text-color]=\"config.legendTextColor || null\"\r\n [style.--legend-font-size]=\"config.legendFontSize ? config.legendFontSize + 'px' : null\"\r\n [style.--legend-font-style]=\"config.legendFontStyle || null\"\r\n [style.--legend-font-weight]=\"config.legendFontWeight || null\"\r\n [style.--legend-text-decoration]=\"config.legendTextDecoration || null\"\r\n [style.--legend-font-family]=\"config.legendFontFamily || 'initial'\"\r\n >\r\n @for (group of groupedItems; track trackByGroup($index, group)) {\r\n @if (group.group) {\r\n <div class=\"chart-legend__group-label\">{{ group.group }}</div>\r\n }\r\n\r\n @for (item of group.items; track trackByItem($index, item)) {\r\n <button\r\n type=\"button\"\r\n class=\"chart-legend__item\"\r\n role=\"switch\"\r\n [class.chart-legend__item--off]=\"!item.selected\"\r\n [class.chart-legend__item--disabled]=\"item.disabled\"\r\n [class.chart-legend__item--hovered]=\"state.hoveredName === item.name\"\r\n [disabled]=\"item.disabled\"\r\n [attr.aria-checked]=\"item.selected\"\r\n [attr.aria-label]=\"item.label\"\r\n [style.--legend-item-color]=\"item.color\"\r\n [title]=\"itemTitle(item)\"\r\n (click)=\"toggle(item, $event)\"\r\n (keydown.enter)=\"toggle(item, $event)\"\r\n (keydown.space)=\"toggle(item, $event)\"\r\n (mouseenter)=\"hover(item)\"\r\n (focus)=\"hover(item)\"\r\n (mouseleave)=\"leave(item)\"\r\n (blur)=\"leave(item)\"\r\n >\r\n @if (templateFor(item); as template) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"template\"\r\n [ngTemplateOutletContext]=\"templateContext(item)\"\r\n ></ng-container>\r\n } @else {\r\n @switch (iconRenderType(item)) {\r\n @case ('image') {\r\n @if (isLineMarker(item)) {\r\n <span\r\n class=\"chart-legend__icon chart-legend__icon--line-marker\"\r\n aria-hidden=\"true\"\r\n >\r\n <span class=\"chart-legend__icon-line\"></span>\r\n <img class=\"chart-legend__icon-image\" [src]=\"iconImageSrc(item)\" alt=\"\" />\r\n <span class=\"chart-legend__icon-line\"></span>\r\n </span>\r\n } @else {\r\n <img class=\"chart-legend__icon-image\" [src]=\"iconImageSrc(item)\" alt=\"\" />\r\n }\r\n }\r\n @case ('path') {\r\n @if (isLineMarker(item)) {\r\n <span\r\n class=\"chart-legend__icon chart-legend__icon--line-marker\"\r\n aria-hidden=\"true\"\r\n >\r\n <span class=\"chart-legend__icon-line\"></span>\r\n <svg\r\n class=\"chart-legend__icon-path\"\r\n viewBox=\"-512 -512 1024 1024\"\r\n aria-hidden=\"true\"\r\n >\r\n <path [attr.d]=\"iconPathData(item)\"></path>\r\n </svg>\r\n <span class=\"chart-legend__icon-line\"></span>\r\n </span>\r\n } @else {\r\n <svg\r\n class=\"chart-legend__icon-path\"\r\n viewBox=\"-512 -512 1024 1024\"\r\n aria-hidden=\"true\"\r\n >\r\n <path [attr.d]=\"iconPathData(item)\"></path>\r\n </svg>\r\n }\r\n }\r\n @case ('shape') {\r\n @if (isLineMarker(item)) {\r\n <span\r\n class=\"chart-legend__icon chart-legend__icon--line-marker\"\r\n aria-hidden=\"true\"\r\n >\r\n <span class=\"chart-legend__icon-line\"></span>\r\n <span\r\n class=\"chart-legend__icon chart-legend__icon--marker\"\r\n [ngClass]=\"iconShapeClass(item.icon)\"\r\n ></span>\r\n <span class=\"chart-legend__icon-line\"></span>\r\n </span>\r\n } @else {\r\n <span\r\n class=\"chart-legend__icon\"\r\n [ngClass]=\"iconShapeClass(iconForRender(item))\"\r\n aria-hidden=\"true\"\r\n ></span>\r\n }\r\n }\r\n }\r\n <span class=\"chart-legend__label\">\n {{ item.label }}@if (this.config.showValue && this.config.valueFormatter) {\n :\n }\n </span>\n @if (this.config.showValue && this.config.valueFormatter) {\r\n <span class=\"chart-legend__value\">{{ this.config.valueFormatter(item) }}</span>\r\n }\r\n @if (this.config.showActionArrow) {\r\n @if (this.config.actionArrowTemplate) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"this.config.actionArrowTemplate\"\r\n [ngTemplateOutletContext]=\"templateContext(item)\"\r\n ></ng-container>\r\n } @else {\r\n <svg\r\n class=\"chart-legend__action-arrow\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n >\r\n <polyline points=\"9 18 15 12 9 6\"></polyline>\r\n </svg>\r\n }\r\n }\r\n }\r\n </button>\r\n }\r\n }\r\n </div>\r\n </div>\r\n\r\n @if (usesInternalLegendScroll && canScrollLegend) {\r\n <button\r\n type=\"button\"\r\n class=\"chart-legend__scroll-button chart-legend__scroll-button--end\"\r\n [disabled]=\"!canScrollEnd\"\r\n (click)=\"scrollLegend(1, $event)\"\r\n [attr.aria-label]=\"scrollEndAriaLabel\"\r\n >\r\n <img\r\n src=\"images/legend_right.svg\"\r\n [class.chart-legend__scroll-icon--down]=\"scrollsVertically\"\r\n alt=\"right\"\r\n />\r\n </button>\r\n }\r\n </div>\r\n\r\n @if (config.showPagination && pageCount > 1) {\r\n <div class=\"chart-legend__pagination\" aria-label=\"Legend pages\">\r\n <button\r\n type=\"button\"\r\n class=\"chart-legend__page\"\r\n [disabled]=\"state.pageIndex === 0\"\r\n (click)=\"page(-1)\"\r\n aria-label=\"Previous legend page\"\r\n >\r\n <\r\n </button>\r\n <span class=\"chart-legend__page-count\">{{ state.pageIndex + 1 }} / {{ pageCount }}</span>\r\n <button\r\n type=\"button\"\r\n class=\"chart-legend__page\"\r\n [disabled]=\"state.pageIndex + 1 === pageCount\"\r\n (click)=\"page(1)\"\r\n aria-label=\"Next legend page\"\r\n >\r\n >\r\n </button>\r\n </div>\r\n }\r\n </nav>\r\n}\r\n", styles: [":host{display:block;min-height:0;min-width:0}.chart-legend{--legend-text-color: #040d17;--legend-muted-color: #8a94a6;--legend-border-color: #eaf3fd;--legend-hover-bg: rgba(15, 23, 42, .04);--legend-font-size: 14px;--legend-item-min-height: 28px;--legend-row-gap: 8px;--legend-column-gap: 12px;--legend-font-style: normal;--legend-font-weight: 400;--legend-text-decoration: none;--legend-font-family: initial;--legend-title-color: #040d17;--legend-title-font-size: 14px;--legend-title-font-style: normal;--legend-title-font-weight: 400;--legend-title-text-decoration: none;--legend-title-font-family: initial;box-sizing:border-box;min-height:0;min-width:0;width:100%}:host-context(.dark) .chart-legend,:host-context([data-theme=dark]) .chart-legend{--legend-text-color: #e5e7eb;--legend-muted-color: #9ca3af;--legend-border-color: #374151;--legend-hover-bg: rgba(255, 255, 255, .08)}.chart-legend__viewport{align-items:center;display:flex;gap:4px;min-width:0;width:100%}.chart-legend__viewport .chart-legend-title{font-weight:var(--legend-title-font-weight);font-size:var(--legend-title-font-size);font-style:var(--legend-title-font-style);text-decoration:var(--legend-title-text-decoration);font-family:var(--legend-title-font-family);color:var(--legend-title-color);white-space:nowrap;margin:0 8px 0 0}.chart-legend__viewport .chart-legend-title--uppercase{text-transform:uppercase}.chart-legend__viewport .chart-legend-title--lowercase{text-transform:lowercase}.chart-legend__viewport .chart-legend-title--capitalize{text-transform:capitalize}.chart-legend__scroller{flex:1 1 auto;min-height:0;min-width:0;overflow-x:hidden;overflow-y:hidden;scrollbar-width:none}.chart-legend__scroller::-webkit-scrollbar{display:none}.chart-legend--scrollable .chart-legend__scroller{overflow-x:auto;overscroll-behavior-x:contain}.chart-legend--scrollable .chart-legend__scroller::-webkit-scrollbar{display:block;height:6px}.chart-legend__items{display:flex;flex-wrap:nowrap;align-items:center;gap:var(--legend-row-gap) var(--legend-column-gap);min-width:0;color:var(--legend-text-color);font-size:var(--legend-font-size);font-style:var(--legend-font-style);font-weight:var(--legend-font-weight);text-decoration:var(--legend-text-decoration);font-family:var(--legend-font-family)}.chart-legend--scrollable .chart-legend__items{min-width:max-content}.chart-legend--wrap:not(.chart-legend--vertical) .chart-legend__items{flex-wrap:wrap;width:100%}.chart-legend--limited-wrap:not(.chart-legend--vertical) .chart-legend__scroller{max-height:calc(var(--legend-item-min-height) * 2 + var(--legend-row-gap));overflow-y:auto;overscroll-behavior-y:contain}.chart-legend--vertical{height:100%}.chart-legend--vertical .chart-legend__viewport{align-items:stretch;flex-direction:column;height:100%;min-height:0}.chart-legend--vertical .chart-legend__scroller{overflow-x:hidden;overflow-y:hidden}.chart-legend--vertical.chart-legend--scrollable .chart-legend__scroller{overflow-y:auto;overscroll-behavior-y:contain}.chart-legend--vertical .chart-legend__items{align-items:stretch;flex-direction:column;min-width:0;width:100%;height:100%}.chart-legend--vertical.chart-legend--wrap .chart-legend__items{align-content:start;display:grid;grid-auto-flow:column;grid-auto-columns:max-content;grid-template-rows:repeat(auto-fit,minmax(28px,max-content));height:100%;justify-content:start;width:auto}.chart-legend--vertical.chart-legend--limited-wrap .chart-legend__viewport{flex-direction:row}.chart-legend--vertical.chart-legend--limited-wrap .chart-legend__scroller{overflow-x:auto;overflow-y:hidden;overscroll-behavior-x:contain}.chart-legend--vertical.chart-legend--limited-wrap .chart-legend__items{grid-auto-columns:minmax(1,calc((100% - var(--legend-column-gap)) / 2));width:max-content}.chart-legend__items--center{justify-content:center}.chart-legend__items--end{justify-content:flex-end}.chart-legend--vertical.chart-legend--wrap .chart-legend__items--center{align-content:center;justify-content:start}.chart-legend--vertical.chart-legend--wrap .chart-legend__items--end{align-content:end;justify-content:start}.chart-legend__group-label{flex:0 0 auto;color:var(--legend-muted-color);font-size:12px;font-weight:600;line-height:1.2;margin-top:4px}.chart-legend__item{--legend-item-color: #64748b;align-items:center;background:color-mix(in srgb,var(--legend-item-color) 4%,transparent);border:1px solid color-mix(in srgb,var(--legend-item-color) 25%,transparent);border-radius:4px;color:inherit;cursor:pointer;display:inline-flex;font:inherit;gap:8px;line-height:1.2;min-height:28px;min-width:0;padding:4px 8px;touch-action:manipulation;transition:background-color .14s ease,border-color .14s ease,opacity .14s ease}.chart-legend--vertical .chart-legend__item{justify-content:flex-start;width:100%}.chart-legend--vertical.chart-legend--wrap .chart-legend__item{width:auto}.chart-legend--vertical.chart-legend--limited-wrap .chart-legend__item{width:100%}.chart-legend__scroll-button{align-items:center;background:transparent;border:1px solid var(--legend-border-color);border-radius:6px;color:inherit;cursor:pointer;display:inline-flex;flex:0 0 auto;font:inherit;height:28px;justify-content:center;line-height:1;width:28px}.chart-legend--vertical .chart-legend__scroll-button{width:100%}.chart-legend--vertical.chart-legend--limited-wrap .chart-legend__scroll-button{height:auto;min-height:28px;width:28px}.chart-legend__scroll-button img{display:block;height:10px;width:10px}.chart-legend__scroll-icon--up,.chart-legend__scroll-icon--down{transform:rotate(90deg)}.chart-legend__scroll-button:disabled{cursor:default;opacity:.42}.chart-legend__item:hover,.chart-legend__item:focus-visible,.chart-legend__item--hovered{outline:none}.chart-legend__item--off{color:var(--legend-muted-color);filter:grayscale(1);opacity:.68}.chart-legend__item--disabled{cursor:not-allowed;opacity:.48}.chart-legend__icon,.chart-legend__icon-image,.chart-legend__icon-path{--legend-icon-size: 12px;background:var(--legend-item-color);box-sizing:border-box;display:inline-block;flex:0 0 auto;height:var(--legend-icon-size);width:var(--legend-icon-size)}.chart-legend__icon-image,.chart-legend__icon-path{background:transparent;object-fit:contain}.chart-legend__icon-path path{fill:var(--legend-item-color);stroke:var(--legend-item-color)}.chart-legend__icon--line,.chart-legend__icon--emptyLine{height:11px;border-radius:999px;background:linear-gradient(to bottom,transparent 0 4px,var(--legend-item-color) 4px 6px,transparent 6px 100%)}.chart-legend__icon--emptyLine{background:linear-gradient(to bottom,transparent 0 4px,var(--legend-item-color) 4px 6px,transparent 6px 100%)}.chart-legend__icon--area{background:linear-gradient(to bottom,var(--legend-item-color),color-mix(in srgb,var(--legend-item-color) 12%,transparent));border-top:3px solid var(--legend-item-color)}.chart-legend__icon--circle{border-radius:50%}.chart-legend__icon--emptyCircle{background:transparent;border:2px solid var(--legend-item-color);border-radius:50%}.chart-legend__icon--rect,.chart-legend__icon--emptyRect,.chart-legend__icon--square,.chart-legend__icon--emptySquare{border-radius:2px}.chart-legend__icon--emptyRect,.chart-legend__icon--emptySquare{background:transparent;border:2px solid var(--legend-item-color)}.chart-legend__icon--roundRect,.chart-legend__icon--emptyRoundRect{border-radius:6px}.chart-legend__icon--emptyRoundRect{background:transparent;border:2px solid var(--legend-item-color)}.chart-legend__icon--triangle,.chart-legend__icon--emptyTriangle{clip-path:polygon(50% 0,100% 100%,0 100%)}.chart-legend__icon--emptyTriangle{background:var(--legend-item-color)}.chart-legend__icon--diamond,.chart-legend__icon--emptyDiamond{transform:rotate(45deg)}.chart-legend__icon--emptyDiamond{background:transparent;border:2px solid var(--legend-item-color)}.chart-legend__icon--pin,.chart-legend__icon--emptyPin{border-radius:50% 50% 50% 0;transform:rotate(-45deg)}.chart-legend__icon--emptyPin{background:transparent;border:2px solid var(--legend-item-color)}.chart-legend__icon--arrow,.chart-legend__icon--emptyArrow{clip-path:polygon(0 35%,58% 35%,58% 10%,100% 50%,58% 90%,58% 65%,0 65%)}.chart-legend__icon--emptyArrow{opacity:.72}.chart-legend__icon--x,.chart-legend__icon--plus,.chart-legend__icon--thickLine{background:transparent;position:relative}.chart-legend__icon--x:before,.chart-legend__icon--x:after,.chart-legend__icon--plus:before,.chart-legend__icon--plus:after{content:\"\";position:absolute;left:50%;top:50%;width:100%;height:2px;background:var(--legend-item-color);border-radius:999px;transform:translate(-50%,-50%)}.chart-legend__icon--x:before{transform:translate(-50%,-50%) rotate(45deg)}.chart-legend__icon--x:after{transform:translate(-50%,-50%) rotate(-45deg)}.chart-legend__icon--plus:after{transform:translate(-50%,-50%) rotate(90deg)}.chart-legend__icon--thickLine{height:4px;width:var(--legend-icon-size);border-radius:999px;background:var(--legend-item-color)}.chart-legend__icon--line-marker{display:inline-flex;align-items:center;justify-content:center;padding:0 2px;background:transparent;border:none;min-width:0;width:auto}.chart-legend__icon-line{flex:1 1 1;min-width:8px;height:2px;background:var(--legend-item-color);border-radius:999px}.chart-legend__item--off .chart-legend__icon,.chart-legend__item--off .chart-legend__icon-path path{filter:grayscale(1);opacity:.68}.chart-legend__item--off .chart-legend__icon--emptyCircle,.chart-legend__item--off .chart-legend__icon--emptyRect,.chart-legend__item--off .chart-legend__icon--emptyRoundRect,.chart-legend__item--off .chart-legend__icon--emptySquare,.chart-legend__item--off .chart-legend__icon--emptyDiamond,.chart-legend__item--off .chart-legend__icon--emptyPin,.chart-legend__item--off .chart-legend__icon--emptyLine{filter:grayscale(1);opacity:.68}.chart-legend__content{display:flex;align-items:center;justify-content:space-between;gap:1rem}.chart-legend__value{font-weight:600;font-size:inherit;font-family:inherit}.chart-legend__item--off .chart-legend__icon--emptyTriangle{filter:grayscale(1);opacity:.68}.chart-legend__label{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:inherit;font-family:inherit}.chart-legend__pagination{align-items:center;display:flex;gap:8px;justify-content:flex-end;margin-top:8px}.chart-legend__page{align-items:center;background:transparent;border:1px solid var(--legend-border-color);border-radius:6px;color:inherit;cursor:pointer;display:inline-flex;font:inherit;height:28px;justify-content:center;width:28px}.chart-legend__page:disabled{cursor:default;opacity:.42}.chart-legend__page-count{color:var(--legend-muted-color);font-size:12px}@media (max-width: 640px){.chart-legend__items{padding-bottom:2px}}.chart-legend__action-arrow{width:12px;height:12px;color:var(--legend-muted-color, #9ca3af);flex:0 0 auto}\n"] }]
|
|
454
454
|
}], ctorParameters: () => [{ type: ChartLegendAdapter }, { type: i0.ChangeDetectorRef }, { type: undefined, decorators: [{
|
|
455
455
|
type: Inject,
|
|
456
456
|
args: [PLATFORM_ID]
|
|
@@ -3823,20 +3823,23 @@ echarts.use([SankeyChart$1, TooltipComponent, TitleComponent, LegendComponent, C
|
|
|
3823
3823
|
class SankeyChart {
|
|
3824
3824
|
chartService;
|
|
3825
3825
|
cdr;
|
|
3826
|
+
hostElement;
|
|
3826
3827
|
config;
|
|
3827
3828
|
theme;
|
|
3828
3829
|
events = [];
|
|
3829
3830
|
chartEvent = new EventEmitter();
|
|
3830
3831
|
legendEvent = new EventEmitter();
|
|
3831
|
-
constructor(chartService, cdr) {
|
|
3832
|
+
constructor(chartService, cdr, hostElement) {
|
|
3832
3833
|
this.chartService = chartService;
|
|
3833
3834
|
this.cdr = cdr;
|
|
3835
|
+
this.hostElement = hostElement;
|
|
3834
3836
|
}
|
|
3835
3837
|
chartOption = {};
|
|
3836
3838
|
chartInstance;
|
|
3837
3839
|
sourceToggleItems = [];
|
|
3838
3840
|
legendSeries = [];
|
|
3839
3841
|
previousReactiveSignature = '';
|
|
3842
|
+
resizeObserver;
|
|
3840
3843
|
/* ------------------ CHANGE HANDLING ------------------ */
|
|
3841
3844
|
ngOnChanges(changes) {
|
|
3842
3845
|
if (!this.config)
|
|
@@ -3966,6 +3969,12 @@ class SankeyChart {
|
|
|
3966
3969
|
},
|
|
3967
3970
|
label: {
|
|
3968
3971
|
show: styling?.labels?.showLabels ?? true,
|
|
3972
|
+
// Keep labels within the space between Sankey columns. ECharts then
|
|
3973
|
+
// adds an ellipsis whenever a larger font, wider node, or long name
|
|
3974
|
+
// does not fit.
|
|
3975
|
+
width: this.resolveSankeyLabelWidth(visibleNodeMeta),
|
|
3976
|
+
overflow: 'truncate',
|
|
3977
|
+
ellipsis: '...',
|
|
3969
3978
|
color: fontColor,
|
|
3970
3979
|
fontFamily: labelTypography?.reset ? undefined : labelTypography?.fontFamily,
|
|
3971
3980
|
fontSize: this.clamp(labelTypography?.reset ? undefined : labelTypography?.fontSize, 8, 40),
|
|
@@ -4002,6 +4011,8 @@ class SankeyChart {
|
|
|
4002
4011
|
get legendConfig() {
|
|
4003
4012
|
const config = this.config?.styling?.legend;
|
|
4004
4013
|
const text = config?.text;
|
|
4014
|
+
const titleStyle = config?.titleStyle;
|
|
4015
|
+
const showValueLabels = config?.showValueLabels === true;
|
|
4005
4016
|
return {
|
|
4006
4017
|
enabled: this.showLegend,
|
|
4007
4018
|
position: config?.position ?? 'bottom',
|
|
@@ -4009,15 +4020,32 @@ class SankeyChart {
|
|
|
4009
4020
|
layout: this.isSideLegend ? 'vertical' : 'horizontal',
|
|
4010
4021
|
scrollable: true,
|
|
4011
4022
|
title: config?.title,
|
|
4012
|
-
|
|
4013
|
-
|
|
4023
|
+
legendTitleTextColor: titleStyle?.color,
|
|
4024
|
+
legendTitleFontSize: this.clamp(titleStyle?.fontSize, 8, 40),
|
|
4025
|
+
legendTitleFontFamily: titleStyle?.fontFamily,
|
|
4026
|
+
legendTitleFontWeight: titleStyle?.bold ? 'bold' : undefined,
|
|
4027
|
+
legendTitleFontStyle: titleStyle?.italic ? 'italic' : undefined,
|
|
4028
|
+
legendTitleTextDecoration: titleStyle?.underline ? 'underline' : undefined,
|
|
4029
|
+
legendTitleTransform: titleStyle?.case === 'none' ? undefined : titleStyle?.case,
|
|
4030
|
+
// Sankey legends are informational: selecting an item must not hide a flow.
|
|
4031
|
+
preventLegendClickDefault: true,
|
|
4032
|
+
hoverLink: false,
|
|
4033
|
+
legendType: config?.legendType ?? config?.style ?? 'marker',
|
|
4034
|
+
icon: config?.icon ?? 'circle',
|
|
4035
|
+
// Use a strict boolean check because configuration values can arrive as the
|
|
4036
|
+
// string "false" from form controls; that must not be rendered as a value.
|
|
4037
|
+
showValue: showValueLabels,
|
|
4014
4038
|
legendTextColor: text?.color,
|
|
4015
4039
|
legendFontSize: this.clamp(text?.fontSize, 8, 40),
|
|
4016
4040
|
legendFontFamily: text?.fontFamily,
|
|
4017
4041
|
legendFontWeight: text?.bold ? 'bold' : undefined,
|
|
4018
4042
|
legendFontStyle: text?.italic ? 'italic' : undefined,
|
|
4019
4043
|
legendTextDecoration: text?.underline ? 'underline' : undefined,
|
|
4020
|
-
|
|
4044
|
+
...(showValueLabels
|
|
4045
|
+
? {
|
|
4046
|
+
valueFormatter: (item) => this.aggregateLegendValue(item?.raw?.data ?? [], config?.aggregation),
|
|
4047
|
+
}
|
|
4048
|
+
: {}),
|
|
4021
4049
|
};
|
|
4022
4050
|
}
|
|
4023
4051
|
toggleSourceNode(name, visible) {
|
|
@@ -4208,6 +4236,16 @@ class SankeyChart {
|
|
|
4208
4236
|
return alignment;
|
|
4209
4237
|
return 'left';
|
|
4210
4238
|
}
|
|
4239
|
+
resolveSankeyLabelWidth(meta) {
|
|
4240
|
+
const chartWidth = this.chartInstance?.getWidth?.() ?? 0;
|
|
4241
|
+
const levelCount = Math.max(...[...meta.values()].map((node) => node.depth), 0) + 1;
|
|
4242
|
+
const nodeWidth = this.clamp(this.config.styling?.node?.thickness ?? this.config.seriesOption?.nodeWidth, 1, 50) ?? 20;
|
|
4243
|
+
const horizontalPadding = 32;
|
|
4244
|
+
const availableWidth = Math.max(chartWidth - horizontalPadding - levelCount * nodeWidth, 0);
|
|
4245
|
+
// A label can occupy half of each gap between adjacent Sankey columns.
|
|
4246
|
+
// Cap it so a simple two-column Sankey does not create excessively long labels.
|
|
4247
|
+
return Math.max(32, Math.min(180, Math.floor(availableWidth / Math.max(levelCount * 2, 1))));
|
|
4248
|
+
}
|
|
4211
4249
|
totalSourceValue(links, meta) {
|
|
4212
4250
|
const sourceNames = new Set([...meta.values()].filter((node) => node.role === 'source').map((node) => node.name));
|
|
4213
4251
|
const total = links
|
|
@@ -4336,6 +4374,17 @@ class SankeyChart {
|
|
|
4336
4374
|
this.buildOption();
|
|
4337
4375
|
this.bindEvents();
|
|
4338
4376
|
}
|
|
4377
|
+
ngAfterViewInit() {
|
|
4378
|
+
if (typeof ResizeObserver === 'undefined')
|
|
4379
|
+
return;
|
|
4380
|
+
this.resizeObserver = new ResizeObserver(() => {
|
|
4381
|
+
if (!this.chartInstance)
|
|
4382
|
+
return;
|
|
4383
|
+
this.chartInstance.resize();
|
|
4384
|
+
this.buildOption();
|
|
4385
|
+
});
|
|
4386
|
+
this.resizeObserver.observe(this.hostElement.nativeElement);
|
|
4387
|
+
}
|
|
4339
4388
|
/* ------------------ EVENTS ------------------ */
|
|
4340
4389
|
bindEvents() {
|
|
4341
4390
|
if (!this.chartInstance)
|
|
@@ -4355,18 +4404,19 @@ class SankeyChart {
|
|
|
4355
4404
|
}
|
|
4356
4405
|
/* ------------------ DESTROY ------------------ */
|
|
4357
4406
|
ngOnDestroy() {
|
|
4407
|
+
this.resizeObserver?.disconnect();
|
|
4358
4408
|
if (this.chartInstance) {
|
|
4359
4409
|
this.chartInstance.off();
|
|
4360
4410
|
this.chartInstance.dispose();
|
|
4361
4411
|
}
|
|
4362
4412
|
}
|
|
4363
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: SankeyChart, deps: [{ token: Charts }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
4413
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: SankeyChart, deps: [{ token: Charts }, { token: i0.ChangeDetectorRef }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
4364
4414
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: SankeyChart, isStandalone: true, selector: "lib-sankey-chart", inputs: { config: "config", theme: "theme", events: "events" }, outputs: { chartEvent: "chartEvent", legendEvent: "legendEvent" }, providers: [provideEchartsCore({ echarts })], usesOnChanges: true, ngImport: i0, template: "<div\n class=\"sankey-chart-shell\"\n [class.sankey-chart-shell--legend-left]=\"legendPosition === 'left'\"\n [class.sankey-chart-shell--legend-right]=\"legendPosition === 'right'\"\n [class.sankey-chart-shell--legend-bottom]=\"legendPosition === 'bottom'\"\n [class.sankey-chart-shell--with-toggles]=\"showNodeToggles\"\n>\n @if (showNodeToggles && sourceToggleItems.length) {\n <div class=\"sankey-node-toggles\" aria-label=\"Sankey source visibility\">\n @for (item of sourceToggleItems; track item.name) {\n <label class=\"sankey-node-toggle\">\n <input\n type=\"checkbox\"\n [checked]=\"!item.hidden\"\n (change)=\"toggleSourceNode(item.name, $any($event.target).checked)\"\n />\n <span>{{ item.name }}</span>\n </label>\n }\n </div>\n }\n\n @if (showLegend && legendPosition !== 'bottom' && legendPosition !== 'right') {\n <lib-chart-legend\n class=\"sankey-chart-shell__legend\"\n [chart]=\"chartInstance\"\n [series]=\"legendSeries\"\n [colors]=\"config.colors || []\"\n [config]=\"legendConfig\"\n (legendEvent)=\"onLegendEvent($event)\"\n ></lib-chart-legend>\n }\n\n <div\n echarts\n [options]=\"chartOption\"\n [theme]=\"theme\"\n class=\"chart-container\"\n (chartInit)=\"onChartInit($event)\"\n ></div>\n\n @if (showLegend && (legendPosition === 'bottom' || legendPosition === 'right')) {\n <lib-chart-legend\n class=\"sankey-chart-shell__legend\"\n [chart]=\"chartInstance\"\n [series]=\"legendSeries\"\n [colors]=\"config.colors || []\"\n [config]=\"legendConfig\"\n (legendEvent)=\"onLegendEvent($event)\"\n ></lib-chart-legend>\n }\n</div>\n", styles: [".sankey-chart-shell{display:flex;width:100%;height:100%;min-width:0;min-height:0;flex-direction:column;gap:8px}.sankey-chart-shell--legend-left,.sankey-chart-shell--legend-right{flex-direction:row}.sankey-chart-shell--legend-bottom{flex-direction:column}.chart-container{flex:1 1 auto;min-width:0;min-height:0;width:100%;height:100%}.sankey-chart-shell__legend{flex:0 0 auto}.sankey-chart-shell--legend-left .sankey-chart-shell__legend,.sankey-chart-shell--legend-right .sankey-chart-shell__legend{max-width:min(320px,40%)}.sankey-node-toggles{display:flex;flex:0 0 auto;flex-wrap:wrap;gap:8px;align-items:center;min-width:0}.sankey-node-toggle{display:inline-flex;align-items:center;gap:6px;min-height:28px;padding:0 10px;border:1px solid #d7d9dd;border-radius:6px;box-sizing:border-box;background:#fff;color:#252a31;font-family:inherit;font-size:12px;line-height:1;cursor:pointer}.sankey-node-toggle input{width:14px;height:14px;margin:0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: NgxEchartsDirective, selector: "echarts, [echarts]", inputs: ["options", "theme", "initOpts", "merge", "autoResize", "loading", "loadingType", "loadingOpts"], outputs: ["chartInit", "optionsError", "chartClick", "chartDblClick", "chartMouseDown", "chartMouseMove", "chartMouseUp", "chartMouseOver", "chartMouseOut", "chartGlobalOut", "chartContextMenu", "chartHighlight", "chartDownplay", "chartSelectChanged", "chartLegendSelectChanged", "chartLegendSelected", "chartLegendUnselected", "chartLegendLegendSelectAll", "chartLegendLegendInverseSelect", "chartLegendScroll", "chartDataZoom", "chartDataRangeSelected", "chartGraphRoam", "chartGeoRoam", "chartTreeRoam", "chartTimelineChanged", "chartTimelinePlayChanged", "chartRestore", "chartDataViewChanged", "chartMagicTypeChanged", "chartGeoSelectChanged", "chartGeoSelected", "chartGeoUnselected", "chartAxisAreaSelected", "chartBrush", "chartBrushEnd", "chartBrushSelected", "chartGlobalCursorTaken", "chartRendered", "chartFinished"], exportAs: ["echarts"] }, { kind: "component", type: ChartLegendComponent, selector: "lib-chart-legend", inputs: ["chart", "series", "colors", "config", "itemTemplate"], outputs: ["legendEvent"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
4365
4415
|
}
|
|
4366
4416
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: SankeyChart, decorators: [{
|
|
4367
4417
|
type: Component,
|
|
4368
4418
|
args: [{ selector: 'lib-sankey-chart', imports: [CommonModule, NgxEchartsDirective, ChartLegendComponent], providers: [provideEchartsCore({ echarts })], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n class=\"sankey-chart-shell\"\n [class.sankey-chart-shell--legend-left]=\"legendPosition === 'left'\"\n [class.sankey-chart-shell--legend-right]=\"legendPosition === 'right'\"\n [class.sankey-chart-shell--legend-bottom]=\"legendPosition === 'bottom'\"\n [class.sankey-chart-shell--with-toggles]=\"showNodeToggles\"\n>\n @if (showNodeToggles && sourceToggleItems.length) {\n <div class=\"sankey-node-toggles\" aria-label=\"Sankey source visibility\">\n @for (item of sourceToggleItems; track item.name) {\n <label class=\"sankey-node-toggle\">\n <input\n type=\"checkbox\"\n [checked]=\"!item.hidden\"\n (change)=\"toggleSourceNode(item.name, $any($event.target).checked)\"\n />\n <span>{{ item.name }}</span>\n </label>\n }\n </div>\n }\n\n @if (showLegend && legendPosition !== 'bottom' && legendPosition !== 'right') {\n <lib-chart-legend\n class=\"sankey-chart-shell__legend\"\n [chart]=\"chartInstance\"\n [series]=\"legendSeries\"\n [colors]=\"config.colors || []\"\n [config]=\"legendConfig\"\n (legendEvent)=\"onLegendEvent($event)\"\n ></lib-chart-legend>\n }\n\n <div\n echarts\n [options]=\"chartOption\"\n [theme]=\"theme\"\n class=\"chart-container\"\n (chartInit)=\"onChartInit($event)\"\n ></div>\n\n @if (showLegend && (legendPosition === 'bottom' || legendPosition === 'right')) {\n <lib-chart-legend\n class=\"sankey-chart-shell__legend\"\n [chart]=\"chartInstance\"\n [series]=\"legendSeries\"\n [colors]=\"config.colors || []\"\n [config]=\"legendConfig\"\n (legendEvent)=\"onLegendEvent($event)\"\n ></lib-chart-legend>\n }\n</div>\n", styles: [".sankey-chart-shell{display:flex;width:100%;height:100%;min-width:0;min-height:0;flex-direction:column;gap:8px}.sankey-chart-shell--legend-left,.sankey-chart-shell--legend-right{flex-direction:row}.sankey-chart-shell--legend-bottom{flex-direction:column}.chart-container{flex:1 1 auto;min-width:0;min-height:0;width:100%;height:100%}.sankey-chart-shell__legend{flex:0 0 auto}.sankey-chart-shell--legend-left .sankey-chart-shell__legend,.sankey-chart-shell--legend-right .sankey-chart-shell__legend{max-width:min(320px,40%)}.sankey-node-toggles{display:flex;flex:0 0 auto;flex-wrap:wrap;gap:8px;align-items:center;min-width:0}.sankey-node-toggle{display:inline-flex;align-items:center;gap:6px;min-height:28px;padding:0 10px;border:1px solid #d7d9dd;border-radius:6px;box-sizing:border-box;background:#fff;color:#252a31;font-family:inherit;font-size:12px;line-height:1;cursor:pointer}.sankey-node-toggle input{width:14px;height:14px;margin:0}\n"] }]
|
|
4369
|
-
}], ctorParameters: () => [{ type: Charts }, { type: i0.ChangeDetectorRef }], propDecorators: { config: [{
|
|
4419
|
+
}], ctorParameters: () => [{ type: Charts }, { type: i0.ChangeDetectorRef }, { type: i0.ElementRef }], propDecorators: { config: [{
|
|
4370
4420
|
type: Input
|
|
4371
4421
|
}], theme: [{
|
|
4372
4422
|
type: Input
|
|
@@ -5125,7 +5175,9 @@ class GaugeChart {
|
|
|
5125
5175
|
const range = max - min || 1;
|
|
5126
5176
|
const displayMin = isPercentage ? 0 : min;
|
|
5127
5177
|
const displayMax = isPercentage ? 100 : max;
|
|
5128
|
-
const displayValue = isPercentage
|
|
5178
|
+
const displayValue = isPercentage
|
|
5179
|
+
? this.clamp(((rawValue - min) / range) * 100, 0, 100)
|
|
5180
|
+
: rawValue;
|
|
5129
5181
|
const targetValue = this.toFiniteNumber(this.config.targetValue);
|
|
5130
5182
|
const displayTarget = targetValue === undefined
|
|
5131
5183
|
? undefined
|
|
@@ -5142,9 +5194,9 @@ class GaugeChart {
|
|
|
5142
5194
|
const showMidValue = this.config.showMidValue === true;
|
|
5143
5195
|
const midValueCount = Math.max(Math.floor(this.config.midValueCount ?? 0), 0);
|
|
5144
5196
|
const splitNumber = showMidValue && midValueCount > 0 ? midValueCount + 1 : 1;
|
|
5145
|
-
const
|
|
5197
|
+
const metricNameWidth = this.resolveMetricNameWidth();
|
|
5198
|
+
const metricName = this.truncateMetricName(this.applyTextCase(this.config.name ?? 'Value', style?.metricNameTypography?.case), metricNameWidth, style?.metricNameTypography?.fontSize ?? 10);
|
|
5146
5199
|
const metricValue = this.applyTextCase(this.formatNumber(rawValue, compactNumber, precision), style?.metricValueTypography?.case);
|
|
5147
|
-
const progressShow = this.resolveProgressVisibility(echartStyleOption, conditionalFormatting?.enabled === true);
|
|
5148
5200
|
const generatedGaugeSeries = {
|
|
5149
5201
|
type: 'gauge',
|
|
5150
5202
|
min: displayMin,
|
|
@@ -5155,11 +5207,22 @@ class GaugeChart {
|
|
|
5155
5207
|
radius: DEFAULT_GAUGE_RADIUS,
|
|
5156
5208
|
splitNumber,
|
|
5157
5209
|
progress: {
|
|
5158
|
-
show:
|
|
5210
|
+
show: conditionalFormatting?.type !== 'rule',
|
|
5159
5211
|
roundCap: false,
|
|
5160
5212
|
width: barWidth,
|
|
5161
5213
|
itemStyle: {
|
|
5162
|
-
color:
|
|
5214
|
+
color: conditionalFormatting?.enabled
|
|
5215
|
+
? {
|
|
5216
|
+
type: 'linear',
|
|
5217
|
+
x: 0,
|
|
5218
|
+
y: 0,
|
|
5219
|
+
x2: 1,
|
|
5220
|
+
y2: 0,
|
|
5221
|
+
colorStops: colorStops.map((c) => {
|
|
5222
|
+
return { offset: c?.[0], color: c?.[1] };
|
|
5223
|
+
}),
|
|
5224
|
+
}
|
|
5225
|
+
: activeColor,
|
|
5163
5226
|
borderWidth: borderThickness,
|
|
5164
5227
|
borderColor: borderThickness ? activeColor : undefined,
|
|
5165
5228
|
},
|
|
@@ -5168,7 +5231,11 @@ class GaugeChart {
|
|
|
5168
5231
|
roundCap: false,
|
|
5169
5232
|
lineStyle: {
|
|
5170
5233
|
width: barWidth,
|
|
5171
|
-
|
|
5234
|
+
...(conditionalFormatting?.enabled &&
|
|
5235
|
+
conditionalFormatting?.type === 'rule' && {
|
|
5236
|
+
color: this.getGaugeAxisColors(conditionalFormatting?.rules || [], displayMin, displayMax, displayValue, style?.barColor?.color || '#4378ea', // progress color
|
|
5237
|
+
style?.rangeColor?.color || '#f2f3f5'),
|
|
5238
|
+
}),
|
|
5172
5239
|
opacity: 1,
|
|
5173
5240
|
},
|
|
5174
5241
|
},
|
|
@@ -5228,6 +5295,13 @@ class GaugeChart {
|
|
|
5228
5295
|
color: '#6b7280',
|
|
5229
5296
|
fontSize: 10,
|
|
5230
5297
|
}),
|
|
5298
|
+
// A metric can be a single, very long word. Give the rich-text
|
|
5299
|
+
// token a responsive width so ECharts truncates it instead of
|
|
5300
|
+
// drawing it beyond the gauge's bounds.
|
|
5301
|
+
width: metricNameWidth,
|
|
5302
|
+
overflow: 'truncate',
|
|
5303
|
+
ellipsis: '...',
|
|
5304
|
+
align: 'center',
|
|
5231
5305
|
lineHeight: 16,
|
|
5232
5306
|
},
|
|
5233
5307
|
value: {
|
|
@@ -5246,6 +5320,10 @@ class GaugeChart {
|
|
|
5246
5320
|
gaugeSeries['min'] = displayMin;
|
|
5247
5321
|
gaugeSeries['max'] = displayMax;
|
|
5248
5322
|
gaugeSeries['data'] = [{ value: displayValue, name: this.config.name ?? 'Value' }];
|
|
5323
|
+
// Typography set through `style` is the public, dynamic API. Preserve any
|
|
5324
|
+
// other detail options from `seriesOption`, but do not let its rich-text
|
|
5325
|
+
// defaults override the metric name/value styles.
|
|
5326
|
+
gaugeSeries['detail'] = this.deepMerge(gaugeSeries['detail'] ?? {}, generatedGaugeSeries.detail);
|
|
5249
5327
|
const targetPointer = this.calculateTargetPointerGeometry(gaugeSeries);
|
|
5250
5328
|
const generatedChartOption = {
|
|
5251
5329
|
backgroundColor: this.config.backgroundColor ?? 'transparent',
|
|
@@ -5276,7 +5354,7 @@ class GaugeChart {
|
|
|
5276
5354
|
axisLine: {
|
|
5277
5355
|
lineStyle: {
|
|
5278
5356
|
width: 0,
|
|
5279
|
-
color: [
|
|
5357
|
+
color: [1, 'transparent'],
|
|
5280
5358
|
},
|
|
5281
5359
|
},
|
|
5282
5360
|
pointer: {
|
|
@@ -5304,6 +5382,157 @@ class GaugeChart {
|
|
|
5304
5382
|
this.chartInstance.setOption(this.chartOption, true);
|
|
5305
5383
|
}
|
|
5306
5384
|
}
|
|
5385
|
+
getRuleColor(rule) {
|
|
5386
|
+
return this.applyOpacity(rule.color, rule.opacity ?? 100);
|
|
5387
|
+
}
|
|
5388
|
+
clamp(value, min, max) {
|
|
5389
|
+
return Math.max(min, Math.min(max, value));
|
|
5390
|
+
}
|
|
5391
|
+
segmentsToColorStops(segments, min, max) {
|
|
5392
|
+
return segments
|
|
5393
|
+
.filter((segment) => segment.end > segment.start)
|
|
5394
|
+
.map((segment) => [this.clamp((segment.end - min) / (max - min), 0, 1), segment.color]);
|
|
5395
|
+
}
|
|
5396
|
+
convertToGaugeValue(value, unit, min, max, actualValue) {
|
|
5397
|
+
if (unit === 'percentage') {
|
|
5398
|
+
const percentage = this.clamp(value, 0, 100);
|
|
5399
|
+
return min + ((actualValue - min) * percentage) / 100;
|
|
5400
|
+
}
|
|
5401
|
+
return value;
|
|
5402
|
+
}
|
|
5403
|
+
convertRuleToSegment(rule, min, max, actualValue) {
|
|
5404
|
+
const value = this.convertToGaugeValue(rule.value, rule.unit, min, max, actualValue);
|
|
5405
|
+
const valueTo = rule.valueTo !== undefined
|
|
5406
|
+
? this.convertToGaugeValue(rule.valueTo, rule.unit, min, max, actualValue)
|
|
5407
|
+
: undefined;
|
|
5408
|
+
switch (rule.operator) {
|
|
5409
|
+
case '<=':
|
|
5410
|
+
case '<':
|
|
5411
|
+
return {
|
|
5412
|
+
start: min,
|
|
5413
|
+
end: value,
|
|
5414
|
+
color: this.getRuleColor(rule),
|
|
5415
|
+
};
|
|
5416
|
+
case 'between':
|
|
5417
|
+
if (valueTo === undefined) {
|
|
5418
|
+
return null;
|
|
5419
|
+
}
|
|
5420
|
+
return {
|
|
5421
|
+
start: Math.min(value, valueTo),
|
|
5422
|
+
end: Math.max(value, valueTo),
|
|
5423
|
+
color: this.getRuleColor(rule),
|
|
5424
|
+
};
|
|
5425
|
+
case '>=':
|
|
5426
|
+
case '>':
|
|
5427
|
+
return {
|
|
5428
|
+
start: value,
|
|
5429
|
+
end: max,
|
|
5430
|
+
color: this.getRuleColor(rule),
|
|
5431
|
+
};
|
|
5432
|
+
default:
|
|
5433
|
+
return null;
|
|
5434
|
+
}
|
|
5435
|
+
}
|
|
5436
|
+
getGaugeAxisColors(rules, min, max, actualValue, progressColor, axisColor) {
|
|
5437
|
+
if (max <= min) {
|
|
5438
|
+
return [[1, axisColor]];
|
|
5439
|
+
}
|
|
5440
|
+
const actual = this.clamp(actualValue, min, max);
|
|
5441
|
+
// No progress
|
|
5442
|
+
if (actual <= min) {
|
|
5443
|
+
return [[1, axisColor]];
|
|
5444
|
+
}
|
|
5445
|
+
const ruleSegments = rules
|
|
5446
|
+
.map((rule) => this.convertRuleToSegment(rule, min, max, actual))
|
|
5447
|
+
.filter((segment) => segment !== null);
|
|
5448
|
+
/*
|
|
5449
|
+
* Rules are allowed ONLY inside actual progress.
|
|
5450
|
+
*/
|
|
5451
|
+
const clippedRules = ruleSegments
|
|
5452
|
+
.map((rule) => ({
|
|
5453
|
+
...rule,
|
|
5454
|
+
start: Math.max(rule.start, min),
|
|
5455
|
+
end: Math.min(rule.end, actual),
|
|
5456
|
+
}))
|
|
5457
|
+
.filter((rule) => rule.end > rule.start);
|
|
5458
|
+
/*
|
|
5459
|
+
* Build the complete gauge from min → max.
|
|
5460
|
+
*/
|
|
5461
|
+
const segments = [];
|
|
5462
|
+
let cursor = min;
|
|
5463
|
+
/*
|
|
5464
|
+
* Sort rules by start position.
|
|
5465
|
+
*/
|
|
5466
|
+
clippedRules.sort((a, b) => a.start - b.start);
|
|
5467
|
+
for (const rule of clippedRules) {
|
|
5468
|
+
/*
|
|
5469
|
+
* Gap before rule:
|
|
5470
|
+
* use progress color.
|
|
5471
|
+
*/
|
|
5472
|
+
if (rule.start > cursor) {
|
|
5473
|
+
segments.push({
|
|
5474
|
+
start: cursor,
|
|
5475
|
+
end: rule.start,
|
|
5476
|
+
color: progressColor,
|
|
5477
|
+
});
|
|
5478
|
+
}
|
|
5479
|
+
/*
|
|
5480
|
+
* Rule area.
|
|
5481
|
+
*/
|
|
5482
|
+
const start = Math.max(cursor, rule.start);
|
|
5483
|
+
if (rule.end > start) {
|
|
5484
|
+
segments.push({
|
|
5485
|
+
start,
|
|
5486
|
+
end: rule.end,
|
|
5487
|
+
color: rule.color,
|
|
5488
|
+
});
|
|
5489
|
+
cursor = Math.max(cursor, rule.end);
|
|
5490
|
+
}
|
|
5491
|
+
}
|
|
5492
|
+
/*
|
|
5493
|
+
* Remaining area inside actual progress.
|
|
5494
|
+
* Use progress color.
|
|
5495
|
+
*/
|
|
5496
|
+
if (cursor < actual) {
|
|
5497
|
+
segments.push({
|
|
5498
|
+
start: cursor,
|
|
5499
|
+
end: actual,
|
|
5500
|
+
color: progressColor,
|
|
5501
|
+
});
|
|
5502
|
+
}
|
|
5503
|
+
/*
|
|
5504
|
+
* Everything after actual progress:
|
|
5505
|
+
* use axis color.
|
|
5506
|
+
*/
|
|
5507
|
+
if (actual < max) {
|
|
5508
|
+
segments.push({
|
|
5509
|
+
start: actual,
|
|
5510
|
+
end: max,
|
|
5511
|
+
color: axisColor,
|
|
5512
|
+
});
|
|
5513
|
+
}
|
|
5514
|
+
return this.segmentsToColorStops(segments, min, max);
|
|
5515
|
+
}
|
|
5516
|
+
applyOpacity(color, opacity) {
|
|
5517
|
+
const alpha = this.clamp(opacity, 0, 100) / 100;
|
|
5518
|
+
if (color.startsWith('#')) {
|
|
5519
|
+
let hex = color.slice(1);
|
|
5520
|
+
if (hex.length === 3) {
|
|
5521
|
+
hex = hex
|
|
5522
|
+
.split('')
|
|
5523
|
+
.map((char) => char + char)
|
|
5524
|
+
.join('');
|
|
5525
|
+
}
|
|
5526
|
+
if (hex.length === 6) {
|
|
5527
|
+
const number = parseInt(hex, 16);
|
|
5528
|
+
const r = (number >> 16) & 255;
|
|
5529
|
+
const g = (number >> 8) & 255;
|
|
5530
|
+
const b = number & 255;
|
|
5531
|
+
return `rgba(${r}, ${g}, ${b}, ${alpha})`;
|
|
5532
|
+
}
|
|
5533
|
+
}
|
|
5534
|
+
return color;
|
|
5535
|
+
}
|
|
5307
5536
|
onChartInit(ec) {
|
|
5308
5537
|
this.chartInstance = ec;
|
|
5309
5538
|
this.buildOption();
|
|
@@ -5346,7 +5575,8 @@ class GaugeChart {
|
|
|
5346
5575
|
const percentage = this.toFiniteNumber(radiusOption.slice(0, -1));
|
|
5347
5576
|
if (percentage === undefined)
|
|
5348
5577
|
return undefined;
|
|
5349
|
-
return (Math.min(this.chartInstance.getWidth(), this.chartInstance.getHeight()) / 2) *
|
|
5578
|
+
return ((Math.min(this.chartInstance.getWidth(), this.chartInstance.getHeight()) / 2) *
|
|
5579
|
+
(percentage / 100));
|
|
5350
5580
|
}
|
|
5351
5581
|
observeChartResize() {
|
|
5352
5582
|
if (typeof ResizeObserver === 'undefined' || !this.chartInstance)
|
|
@@ -5443,24 +5673,15 @@ class GaugeChart {
|
|
|
5443
5673
|
// width is supplied, so a deliberately thin gauge is not enlarged.
|
|
5444
5674
|
return this.clamp(configuredWidths.length ? Math.max(...configuredWidths) : fallback, 1, 80);
|
|
5445
5675
|
}
|
|
5446
|
-
resolveProgressVisibility(seriesOption, conditionalEnabled) {
|
|
5447
|
-
const configuredProgressShow = seriesOption?.['progress']?.['show'];
|
|
5448
|
-
if (typeof configuredProgressShow === 'boolean')
|
|
5449
|
-
return configuredProgressShow;
|
|
5450
|
-
if (conditionalEnabled)
|
|
5451
|
-
return false;
|
|
5452
|
-
const configuredAxisColors = seriesOption?.['axisLine']?.['lineStyle']?.['color'];
|
|
5453
|
-
if (Array.isArray(configuredAxisColors) && configuredAxisColors.length > 1)
|
|
5454
|
-
return false;
|
|
5455
|
-
return true;
|
|
5456
|
-
}
|
|
5457
5676
|
mergeChartOptions(generatedOption, customOption) {
|
|
5458
5677
|
if (!customOption)
|
|
5459
5678
|
return generatedOption;
|
|
5460
5679
|
const { series, ...customTopLevelOption } = customOption;
|
|
5461
5680
|
const mergedOption = this.deepMerge({ ...generatedOption }, customTopLevelOption);
|
|
5462
5681
|
if (Array.isArray(series)) {
|
|
5463
|
-
const generatedSeries = Array.isArray(generatedOption['series'])
|
|
5682
|
+
const generatedSeries = Array.isArray(generatedOption['series'])
|
|
5683
|
+
? generatedOption['series']
|
|
5684
|
+
: [];
|
|
5464
5685
|
mergedOption['series'] = series.map((seriesOption, index) => this.deepMerge({ ...(generatedSeries[index] ?? {}) }, seriesOption));
|
|
5465
5686
|
if (generatedSeries.length > series.length) {
|
|
5466
5687
|
mergedOption['series'].push(...generatedSeries.slice(series.length));
|
|
@@ -5507,6 +5728,25 @@ class GaugeChart {
|
|
|
5507
5728
|
return 0;
|
|
5508
5729
|
return values.reduce((sum, value) => sum + value, 0);
|
|
5509
5730
|
}
|
|
5731
|
+
resolveMetricNameWidth() {
|
|
5732
|
+
// `buildOption` also runs before chart initialisation. Use a conservative
|
|
5733
|
+
// fallback then recalculate from the actual chart dimensions on init and
|
|
5734
|
+
// resize.
|
|
5735
|
+
const chartWidth = this.chartInstance?.getWidth();
|
|
5736
|
+
if (!chartWidth)
|
|
5737
|
+
return 200;
|
|
5738
|
+
return this.clamp(Math.floor(chartWidth * 0.7), 80, 400);
|
|
5739
|
+
}
|
|
5740
|
+
truncateMetricName(name, availableWidth, fontSize) {
|
|
5741
|
+
// Rich-text overflow is not reliably applied to gauge detail text in all
|
|
5742
|
+
// ECharts renderers. Trim the string before it reaches the formatter so a
|
|
5743
|
+
// long word cannot escape the gauge even when it contains no spaces.
|
|
5744
|
+
const averageCharacterWidth = Math.max(fontSize, 8) * 0.62;
|
|
5745
|
+
const maximumCharacters = Math.max(Math.floor(availableWidth / averageCharacterWidth), 1);
|
|
5746
|
+
return name.length > maximumCharacters
|
|
5747
|
+
? `${name.slice(0, Math.max(maximumCharacters - 3, 1))}...`
|
|
5748
|
+
: name;
|
|
5749
|
+
}
|
|
5510
5750
|
resolveMetricValues() {
|
|
5511
5751
|
return (this.config.data ?? [])
|
|
5512
5752
|
.map((value) => this.toFiniteNumber(value))
|
|
@@ -5621,7 +5861,8 @@ class GaugeChart {
|
|
|
5621
5861
|
return false;
|
|
5622
5862
|
if (rule.secondCondition) {
|
|
5623
5863
|
const second = this.ruleValueToNumber(rule.secondCondition.value, rule.secondCondition.unit, min, max);
|
|
5624
|
-
return second !== undefined &&
|
|
5864
|
+
return (second !== undefined &&
|
|
5865
|
+
this.matchesRuleCondition(value, second, rule.secondCondition.operator));
|
|
5625
5866
|
}
|
|
5626
5867
|
return true;
|
|
5627
5868
|
}
|
|
@@ -5638,14 +5879,15 @@ class GaugeChart {
|
|
|
5638
5879
|
case '=':
|
|
5639
5880
|
return value === firstValue;
|
|
5640
5881
|
case 'between':
|
|
5641
|
-
return secondValue !== undefined &&
|
|
5882
|
+
return (secondValue !== undefined &&
|
|
5883
|
+
value >= Math.min(firstValue, secondValue) &&
|
|
5884
|
+
value <= Math.max(firstValue, secondValue));
|
|
5642
5885
|
default:
|
|
5643
5886
|
return false;
|
|
5644
5887
|
}
|
|
5645
5888
|
}
|
|
5646
5889
|
resolveGradientStops(min, max) {
|
|
5647
|
-
const points = [...(this.config.style?.conditionalFormatting?.gradientPoints ?? [])]
|
|
5648
|
-
.sort((a, b) => a.position - b.position);
|
|
5890
|
+
const points = [...(this.config.style?.conditionalFormatting?.gradientPoints ?? [])].sort((a, b) => a.position - b.position);
|
|
5649
5891
|
const normalized = points.length
|
|
5650
5892
|
? points
|
|
5651
5893
|
: [
|
|
@@ -5676,7 +5918,7 @@ class GaugeChart {
|
|
|
5676
5918
|
if (numeric === undefined)
|
|
5677
5919
|
return undefined;
|
|
5678
5920
|
const actual = unit === 'percentage' ? min + (this.clamp(numeric, 0, 100) / 100) * (max - min) : numeric;
|
|
5679
|
-
return this.clamp((actual - min) / (
|
|
5921
|
+
return this.clamp((actual - min) / (max - min || 1), 0, 1);
|
|
5680
5922
|
}
|
|
5681
5923
|
ruleValueToNumber(value, unit, min, max) {
|
|
5682
5924
|
const numericValue = this.toFiniteNumber(value);
|
|
@@ -5786,9 +6028,6 @@ class GaugeChart {
|
|
|
5786
6028
|
}
|
|
5787
6029
|
return undefined;
|
|
5788
6030
|
}
|
|
5789
|
-
clamp(value, min, max) {
|
|
5790
|
-
return Math.min(Math.max(value, min), max);
|
|
5791
|
-
}
|
|
5792
6031
|
ngOnDestroy() {
|
|
5793
6032
|
this.chartResizeObserver?.disconnect();
|
|
5794
6033
|
if (this.chartInstance) {
|