@hestia-earth/ui-components 0.43.20 → 0.43.22
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.
|
@@ -95,6 +95,7 @@ const gitBranch = () => (['dev', 'staging'].some(env => baseUrl().includes(env))
|
|
|
95
95
|
*/
|
|
96
96
|
const windowRef = () => (typeof window === 'undefined' ? undefined : window);
|
|
97
97
|
const origin = () => windowRef()?.location?.origin ?? '';
|
|
98
|
+
const openUrl = (url, target = '_self') => windowRef()?.open(url, target);
|
|
98
99
|
const isChrome = () => windowRef()?.navigator?.userAgent?.includes('Chrome') ?? false;
|
|
99
100
|
const baseUrl = (allowLocalhost = true) => origin().includes('localhost')
|
|
100
101
|
? allowLocalhost
|
|
@@ -173,6 +174,26 @@ const nodeDefaultLabel = {
|
|
|
173
174
|
const defaultLabel = (node) => node
|
|
174
175
|
? (node['@type'] in nodeDefaultLabel ? nodeDefaultLabel[node['@type']](node) : node.name) || node['@id'] || node.id
|
|
175
176
|
: '';
|
|
177
|
+
const labelWithId = (label, id, maxLength) => {
|
|
178
|
+
const suffix = ` (${id})`;
|
|
179
|
+
// `ellipsis` appends 3 characters to the length it is given
|
|
180
|
+
return `${ellipsis(label, Math.max(maxLength - suffix.length - 3, 0))}${suffix}`;
|
|
181
|
+
};
|
|
182
|
+
/**
|
|
183
|
+
* Numbered labels for a list of nodes compared on a chart.
|
|
184
|
+
* Nodes sharing a name are indistinguishable once drawn, so the `@id` is appended to every label
|
|
185
|
+
* that is not unique. The name is shortened to make room for it, as a label longer than `maxLength`
|
|
186
|
+
* is truncated by the chart and would lose the `@id` it was given.
|
|
187
|
+
*/
|
|
188
|
+
const nodeChartLabels = (nodes, maxLength) => {
|
|
189
|
+
const names = (nodes || []).map(node => defaultLabel(node));
|
|
190
|
+
const duplicates = names.filter((name, index) => names.indexOf(name) !== index);
|
|
191
|
+
return names.map((name, index) => {
|
|
192
|
+
const label = `${index + 1}. ${name}`;
|
|
193
|
+
const id = nodes[index]?.['@id'];
|
|
194
|
+
return duplicates.includes(name) && id ? labelWithId(label, id, maxLength) : label;
|
|
195
|
+
});
|
|
196
|
+
};
|
|
176
197
|
/**
|
|
177
198
|
* Stable `@for` track key for a node that uniquely identifies it across data versions.
|
|
178
199
|
* Two nodes with the same `@id` but a different `dataVersion` (e.g. current vs a compared version)
|
|
@@ -1057,6 +1078,9 @@ const methodTierOrder = (methodTier) => [
|
|
|
1057
1078
|
EmissionMethodTier.background,
|
|
1058
1079
|
EmissionMethodTier['not relevant']
|
|
1059
1080
|
].indexOf(methodTier);
|
|
1081
|
+
// an emission also produced by a Transformation is written on the Cycle twice, the second one
|
|
1082
|
+
// "not relevant" with a value of 0 - the tier holding the real value is the one to report under
|
|
1083
|
+
const highestMethodTier = (methodTiers) => methodTiers.filter(Boolean).sort((a, b) => methodTierOrder(a) - methodTierOrder(b))[0];
|
|
1060
1084
|
const grouppedValueKeys = [
|
|
1061
1085
|
'dates',
|
|
1062
1086
|
'sd',
|
|
@@ -1086,12 +1110,14 @@ const groupNodesByTerm = (nodes = [], key, includeNode = (_node) => true, hideZe
|
|
|
1086
1110
|
// (same `@id`, different `dataVersion`) are grouped separately instead of merged
|
|
1087
1111
|
const nodeId = nodeVersionKey(node);
|
|
1088
1112
|
const groupedKey = groupNodeKey(blankNode);
|
|
1089
|
-
|
|
1113
|
+
const methodTier = highestMethodTier([group[groupedKey]?.methodTier, blankNode.methodTier]);
|
|
1114
|
+
group[groupedKey] = {
|
|
1090
1115
|
visible: true,
|
|
1091
1116
|
term: blankNode.term,
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1117
|
+
values: {},
|
|
1118
|
+
...group[groupedKey],
|
|
1119
|
+
methodTier,
|
|
1120
|
+
methodTierOrder: methodTierOrder(methodTier)
|
|
1095
1121
|
};
|
|
1096
1122
|
group[groupedKey].values[nodeId] = group[groupedKey].values[nodeId] || {
|
|
1097
1123
|
index,
|
|
@@ -3657,6 +3683,10 @@ const termKeyToLabel = {
|
|
|
3657
3683
|
agrovoc: 'AGROVOC'
|
|
3658
3684
|
};
|
|
3659
3685
|
const termTypeLabel = (value = 'N/A') => termTypeToLabel[value] || termKeyToLabel[value] || keyToLabel(value);
|
|
3686
|
+
// glossary names are punctuated ("Land transformation, 20 year average") and a reader typing one
|
|
3687
|
+
// leaves the punctuation out, so neither side keeps it
|
|
3688
|
+
const termSearch = (term = '') => term.replace(/[,\s]/g, '').toLowerCase();
|
|
3689
|
+
const suggestTerms = (terms, value) => terms.filter(({ name }) => termSearch(name).includes(termSearch(value)));
|
|
3660
3690
|
|
|
3661
3691
|
class KeyToLabelPipe {
|
|
3662
3692
|
transform(value) {
|
|
@@ -5899,18 +5929,18 @@ class ChartExportButtonComponent {
|
|
|
5899
5929
|
this.close();
|
|
5900
5930
|
}
|
|
5901
5931
|
open() {
|
|
5902
|
-
this.modalService.open(this.modal());
|
|
5932
|
+
this.modalService.open(this.modal(), { windowClass: 'is-above-popover' });
|
|
5903
5933
|
}
|
|
5904
5934
|
close() {
|
|
5905
5935
|
this.exportFormat.set(undefined);
|
|
5906
5936
|
this.modalService.dismissAll();
|
|
5907
5937
|
}
|
|
5908
5938
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ChartExportButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
5909
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: ChartExportButtonComponent, isStandalone: true, selector: "he-chart-export-button", inputs: { buttonClass: { classPropertyName: "buttonClass", publicName: "buttonClass", isSignal: true, isRequired: false, transformFunction: null }, chart: { classPropertyName: "chart", publicName: "chart", isSignal: true, isRequired: false, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null }, exportFormats: { classPropertyName: "exportFormats", publicName: "exportFormats", isSignal: true, isRequired: false, transformFunction: null }, chartExportFn: { classPropertyName: "chartExportFn", publicName: "chartExportFn", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "modal", first: true, predicate: ["modal"], descendants: true, isSignal: true }], ngImport: i0, template: "<button\n class=\"{{ buttonClass() }}\"\n type=\"button\"\n [ngbTooltip]=\"chart()?.exporting() ? '' : 'Download'\"\n placement=\"bottom\"\n (click)=\"open()\">\n <he-svg-icon name=\"download\" />\n</button>\n\n<ng-template #modal>\n <div class=\"modal is-active\">\n <div class=\"modal-background\"></div>\n <div class=\"modal-card\">\n <header class=\"modal-card-head\">\n <p class=\"modal-card-title\">Download Chart</p>\n <button class=\"delete is-small\" aria-label=\"close\" type=\"button\" (click)=\"close()\"></button>\n </header>\n <section class=\"modal-card-body\">\n <p class=\"has-text-secondary is-mb-2\">Download chart as:</p>\n <div class=\"is-flex is-flex-direction-column is-gap-4\">\n @for (format of exportFormats(); track format.extension) {\n <div class=\"is-flex is-gap-4\">\n <div class=\"field is-mb-0\">\n <input\n type=\"checkbox\"\n [id]=\"format.extension\"\n [checked]=\"exportFormat() === format.extension\"\n (change)=\"exportFormat.set(format.extension)\" />\n </div>\n <he-svg-icon name=\"image\" />\n <label class=\"has-text-grey-dark is-clickable\" [for]=\"format.extension\">\n {{ format.label }} (.{{ format.extension }})\n </label>\n </div>\n }\n </div>\n </section>\n <footer class=\"modal-card-foot\">\n <button class=\"button is-primary\" [disabled]=\"!exportFormat()\" (click)=\"download()\">\n @if (chart()?.exporting()) {\n <he-svg-icon name=\"loading\" animation=\"spin\" />\n } @else {\n <he-svg-icon name=\"download\" />\n }\n <span class=\"is-pl-2\">Download</span>\n </button>\n </footer>\n </div>\n </div>\n</ng-template>\n", styles: [""], dependencies: [{ kind: "component", type: HESvgIconComponent, selector: "he-svg-icon", inputs: ["name", "size", "animation"] }, { kind: "directive", type: NgbTooltip, selector: "[ngbTooltip]", inputs: ["animation", "autoClose", "placement", "popperOptions", "triggers", "positionTarget", "container", "disableTooltip", "tooltipClass", "tooltipContext", "openDelay", "closeDelay", "ngbTooltip"], outputs: ["shown", "hidden"], exportAs: ["ngbTooltip"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
5939
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: ChartExportButtonComponent, isStandalone: true, selector: "he-chart-export-button", inputs: { buttonClass: { classPropertyName: "buttonClass", publicName: "buttonClass", isSignal: true, isRequired: false, transformFunction: null }, chart: { classPropertyName: "chart", publicName: "chart", isSignal: true, isRequired: false, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null }, exportFormats: { classPropertyName: "exportFormats", publicName: "exportFormats", isSignal: true, isRequired: false, transformFunction: null }, chartExportFn: { classPropertyName: "chartExportFn", publicName: "chartExportFn", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "modal", first: true, predicate: ["modal"], descendants: true, isSignal: true }], ngImport: i0, template: "<button\n class=\"{{ buttonClass() }}\"\n type=\"button\"\n [ngbTooltip]=\"chart()?.exporting() ? '' : 'Download'\"\n placement=\"bottom\"\n (click)=\"open()\">\n <he-svg-icon name=\"download\" />\n</button>\n\n<ng-template #modal>\n <!-- the chart may sit in a popover closing on outside clicks: keep it open, or the chart is gone -->\n <div class=\"modal is-active\" (mousedown)=\"$event.stopPropagation()\">\n <div class=\"modal-background\"></div>\n <div class=\"modal-card\">\n <header class=\"modal-card-head\">\n <p class=\"modal-card-title\">Download Chart</p>\n <button class=\"delete is-small\" aria-label=\"close\" type=\"button\" (click)=\"close()\"></button>\n </header>\n <section class=\"modal-card-body\">\n <p class=\"has-text-secondary is-mb-2\">Download chart as:</p>\n <div class=\"is-flex is-flex-direction-column is-gap-4\">\n @for (format of exportFormats(); track format.extension) {\n <div class=\"is-flex is-gap-4\">\n <div class=\"field is-mb-0\">\n <input\n type=\"checkbox\"\n [id]=\"format.extension\"\n [checked]=\"exportFormat() === format.extension\"\n (change)=\"exportFormat.set(format.extension)\" />\n </div>\n <he-svg-icon name=\"image\" />\n <label class=\"has-text-grey-dark is-clickable\" [for]=\"format.extension\">\n {{ format.label }} (.{{ format.extension }})\n </label>\n </div>\n }\n </div>\n </section>\n <footer class=\"modal-card-foot\">\n <button class=\"button is-primary\" [disabled]=\"!exportFormat()\" (click)=\"download()\">\n @if (chart()?.exporting()) {\n <he-svg-icon name=\"loading\" animation=\"spin\" />\n } @else {\n <he-svg-icon name=\"download\" />\n }\n <span class=\"is-pl-2\">Download</span>\n </button>\n </footer>\n </div>\n </div>\n</ng-template>\n", styles: [""], dependencies: [{ kind: "component", type: HESvgIconComponent, selector: "he-svg-icon", inputs: ["name", "size", "animation"] }, { kind: "directive", type: NgbTooltip, selector: "[ngbTooltip]", inputs: ["animation", "autoClose", "placement", "popperOptions", "triggers", "positionTarget", "container", "disableTooltip", "tooltipClass", "tooltipContext", "openDelay", "closeDelay", "ngbTooltip"], outputs: ["shown", "hidden"], exportAs: ["ngbTooltip"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
5910
5940
|
}
|
|
5911
5941
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ChartExportButtonComponent, decorators: [{
|
|
5912
5942
|
type: Component$1,
|
|
5913
|
-
args: [{ selector: 'he-chart-export-button', changeDetection: ChangeDetectionStrategy.OnPush, imports: [HESvgIconComponent, NgbTooltip], template: "<button\n class=\"{{ buttonClass() }}\"\n type=\"button\"\n [ngbTooltip]=\"chart()?.exporting() ? '' : 'Download'\"\n placement=\"bottom\"\n (click)=\"open()\">\n <he-svg-icon name=\"download\" />\n</button>\n\n<ng-template #modal>\n <div class=\"modal is-active\">\n <div class=\"modal-background\"></div>\n <div class=\"modal-card\">\n <header class=\"modal-card-head\">\n <p class=\"modal-card-title\">Download Chart</p>\n <button class=\"delete is-small\" aria-label=\"close\" type=\"button\" (click)=\"close()\"></button>\n </header>\n <section class=\"modal-card-body\">\n <p class=\"has-text-secondary is-mb-2\">Download chart as:</p>\n <div class=\"is-flex is-flex-direction-column is-gap-4\">\n @for (format of exportFormats(); track format.extension) {\n <div class=\"is-flex is-gap-4\">\n <div class=\"field is-mb-0\">\n <input\n type=\"checkbox\"\n [id]=\"format.extension\"\n [checked]=\"exportFormat() === format.extension\"\n (change)=\"exportFormat.set(format.extension)\" />\n </div>\n <he-svg-icon name=\"image\" />\n <label class=\"has-text-grey-dark is-clickable\" [for]=\"format.extension\">\n {{ format.label }} (.{{ format.extension }})\n </label>\n </div>\n }\n </div>\n </section>\n <footer class=\"modal-card-foot\">\n <button class=\"button is-primary\" [disabled]=\"!exportFormat()\" (click)=\"download()\">\n @if (chart()?.exporting()) {\n <he-svg-icon name=\"loading\" animation=\"spin\" />\n } @else {\n <he-svg-icon name=\"download\" />\n }\n <span class=\"is-pl-2\">Download</span>\n </button>\n </footer>\n </div>\n </div>\n</ng-template>\n" }]
|
|
5943
|
+
args: [{ selector: 'he-chart-export-button', changeDetection: ChangeDetectionStrategy.OnPush, imports: [HESvgIconComponent, NgbTooltip], template: "<button\n class=\"{{ buttonClass() }}\"\n type=\"button\"\n [ngbTooltip]=\"chart()?.exporting() ? '' : 'Download'\"\n placement=\"bottom\"\n (click)=\"open()\">\n <he-svg-icon name=\"download\" />\n</button>\n\n<ng-template #modal>\n <!-- the chart may sit in a popover closing on outside clicks: keep it open, or the chart is gone -->\n <div class=\"modal is-active\" (mousedown)=\"$event.stopPropagation()\">\n <div class=\"modal-background\"></div>\n <div class=\"modal-card\">\n <header class=\"modal-card-head\">\n <p class=\"modal-card-title\">Download Chart</p>\n <button class=\"delete is-small\" aria-label=\"close\" type=\"button\" (click)=\"close()\"></button>\n </header>\n <section class=\"modal-card-body\">\n <p class=\"has-text-secondary is-mb-2\">Download chart as:</p>\n <div class=\"is-flex is-flex-direction-column is-gap-4\">\n @for (format of exportFormats(); track format.extension) {\n <div class=\"is-flex is-gap-4\">\n <div class=\"field is-mb-0\">\n <input\n type=\"checkbox\"\n [id]=\"format.extension\"\n [checked]=\"exportFormat() === format.extension\"\n (change)=\"exportFormat.set(format.extension)\" />\n </div>\n <he-svg-icon name=\"image\" />\n <label class=\"has-text-grey-dark is-clickable\" [for]=\"format.extension\">\n {{ format.label }} (.{{ format.extension }})\n </label>\n </div>\n }\n </div>\n </section>\n <footer class=\"modal-card-foot\">\n <button class=\"button is-primary\" [disabled]=\"!exportFormat()\" (click)=\"download()\">\n @if (chart()?.exporting()) {\n <he-svg-icon name=\"loading\" animation=\"spin\" />\n } @else {\n <he-svg-icon name=\"download\" />\n }\n <span class=\"is-pl-2\">Download</span>\n </button>\n </footer>\n </div>\n </div>\n</ng-template>\n" }]
|
|
5914
5944
|
}], propDecorators: { modal: [{ type: i0.ViewChild, args: ['modal', { isSignal: true }] }], buttonClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "buttonClass", required: false }] }], chart: [{ type: i0.Input, args: [{ isSignal: true, alias: "chart", required: false }] }], config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: false }] }], exportFormats: [{ type: i0.Input, args: [{ isSignal: true, alias: "exportFormats", required: false }] }], chartExportFn: [{ type: i0.Input, args: [{ isSignal: true, alias: "chartExportFn", required: false }] }] } });
|
|
5915
5945
|
|
|
5916
5946
|
const defaultSettings$5 = Object.freeze({
|
|
@@ -5928,6 +5958,10 @@ const defaultTicksFont = {
|
|
|
5928
5958
|
family: 'Lato',
|
|
5929
5959
|
size: 13
|
|
5930
5960
|
};
|
|
5961
|
+
/**
|
|
5962
|
+
* Maximum length of an axis label, past which the charts truncate it.
|
|
5963
|
+
*/
|
|
5964
|
+
const chartLabelMaxLength = 50;
|
|
5931
5965
|
class ChartComponent {
|
|
5932
5966
|
constructor() {
|
|
5933
5967
|
this.data = input(undefined, ...(ngDevMode ? [{ debugName: "data" }] : []));
|
|
@@ -6064,19 +6098,46 @@ const afterBarDrawPlugin = settings => ({
|
|
|
6064
6098
|
}
|
|
6065
6099
|
});
|
|
6066
6100
|
|
|
6101
|
+
/**
|
|
6102
|
+
* Hover handler turning the pointer into a cursor over a clickable axis label.
|
|
6103
|
+
*/
|
|
6104
|
+
const axisLabelCursor = ({ label, event }) => {
|
|
6105
|
+
const canvas = event?.native?.target;
|
|
6106
|
+
if (label && canvas) {
|
|
6107
|
+
canvas.style.cursor = 'pointer';
|
|
6108
|
+
}
|
|
6109
|
+
};
|
|
6110
|
+
const axisSettings = (chart) => (chart.config.options.plugins?.axisHover || {});
|
|
6111
|
+
const disabled = (chart, { onHoverLabel, onClickLabel }) => !chart.scales.y || (!onHoverLabel && !onClickLabel);
|
|
6112
|
+
const isOverAxis = (scale, event) => event.x != null && event.x >= scale.left && event.x <= scale.right;
|
|
6113
|
+
const tickAt = (scale, y, maxDistance) => {
|
|
6114
|
+
const ticks = scale.getTicks();
|
|
6115
|
+
const position = ticks.findIndex((_, index) => Math.abs(y - scale.getPixelForTick(index)) < maxDistance);
|
|
6116
|
+
return position < 0 ? null : { index: ticks[position].value, y: scale.getPixelForTick(position) };
|
|
6117
|
+
};
|
|
6118
|
+
const labelAt = (chart, index) => (index >= 0 ? chart.data.labels[index] : '');
|
|
6119
|
+
const labelEvent = (chart, event, maxDistance) => {
|
|
6120
|
+
const scale = chart.scales.y;
|
|
6121
|
+
const tick = isOverAxis(scale, event) ? tickAt(scale, event.y, maxDistance) : null;
|
|
6122
|
+
const index = tick ? tick.index : -1;
|
|
6123
|
+
return {
|
|
6124
|
+
label: labelAt(chart, index),
|
|
6125
|
+
index,
|
|
6126
|
+
anchorX: (scale.left + scale.right) / 2,
|
|
6127
|
+
anchorY: (tick ? tick.y : event.y) + maxDistance,
|
|
6128
|
+
event
|
|
6129
|
+
};
|
|
6130
|
+
};
|
|
6131
|
+
const notifyClick = ({ onClickLabel }, data) => data.index >= 0 && data.event.type === 'click' ? onClickLabel?.(data) : undefined;
|
|
6067
6132
|
const axisHoverPlugin = {
|
|
6068
6133
|
id: 'axisHover',
|
|
6069
|
-
afterEvent(chart,
|
|
6070
|
-
const
|
|
6071
|
-
|
|
6072
|
-
|
|
6073
|
-
const
|
|
6074
|
-
|
|
6075
|
-
|
|
6076
|
-
? yScale.getTicks().find((tick, index) => Math.abs(event.y - yScale.getPixelForTick(index)) < maxDistance)
|
|
6077
|
-
: null;
|
|
6078
|
-
const label = closestTick ? chart.data.labels[closestTick.value] : '';
|
|
6079
|
-
onHoverLabel({ label, event });
|
|
6134
|
+
afterEvent(chart, { event }) {
|
|
6135
|
+
const settings = axisSettings(chart);
|
|
6136
|
+
if (disabled(chart, settings))
|
|
6137
|
+
return;
|
|
6138
|
+
const data = labelEvent(chart, event, settings.maxDistance ?? 15);
|
|
6139
|
+
settings.onHoverLabel?.(data);
|
|
6140
|
+
notifyClick(settings, data);
|
|
6080
6141
|
}
|
|
6081
6142
|
};
|
|
6082
6143
|
|
|
@@ -6381,6 +6442,30 @@ const increaseScaleLimits = (scale, handleMinScaleZero = true) => {
|
|
|
6381
6442
|
scale.max += padding;
|
|
6382
6443
|
};
|
|
6383
6444
|
|
|
6445
|
+
// below the row being read, never on it, and never over the plot beside it
|
|
6446
|
+
const placements = ['bottom', 'top'];
|
|
6447
|
+
/**
|
|
6448
|
+
* Hover and click behaviour for axis labels, which are drawn on the canvas and so can carry
|
|
6449
|
+
* neither a `title` nor a link. The tooltip opens once per label rather than on every mouse move,
|
|
6450
|
+
* and the pointer only becomes a cursor where a click does something.
|
|
6451
|
+
*/
|
|
6452
|
+
const axisLabelSettings = (tooltip, tooltipFn, clickFn) => {
|
|
6453
|
+
let openIndex = -1;
|
|
6454
|
+
const moveTooltip = (data) => {
|
|
6455
|
+
openIndex >= 0 && tooltip()?.hide();
|
|
6456
|
+
openIndex = data.index;
|
|
6457
|
+
data.index >= 0 &&
|
|
6458
|
+
tooltip()?.show(data, data.anchorX, data.anchorY, { container: 'body', placement: placements });
|
|
6459
|
+
};
|
|
6460
|
+
return {
|
|
6461
|
+
onHoverLabel: data => {
|
|
6462
|
+
clickFn() && data.label && axisLabelCursor(data);
|
|
6463
|
+
data.index !== openIndex && moveTooltip(data);
|
|
6464
|
+
},
|
|
6465
|
+
onClickLabel: ({ index }) => clickFn()?.(index)
|
|
6466
|
+
};
|
|
6467
|
+
};
|
|
6468
|
+
|
|
6384
6469
|
const registerChart = (items = []) => () => {
|
|
6385
6470
|
Chart.register(BarController, LineController, CategoryScale, LinearScale, PointElement, BarElement, LineElement, Title, Tooltip, Legend, TimeScale, annotationPlugin, ...items);
|
|
6386
6471
|
};
|
|
@@ -6451,7 +6536,7 @@ const defaultSettings$3 = Object.freeze({
|
|
|
6451
6536
|
},
|
|
6452
6537
|
callback: function (value) {
|
|
6453
6538
|
const label = this.getLabelForValue(value);
|
|
6454
|
-
return ellipsis$1(label,
|
|
6539
|
+
return ellipsis$1(label, chartLabelMaxLength);
|
|
6455
6540
|
}
|
|
6456
6541
|
}
|
|
6457
6542
|
}
|
|
@@ -6746,7 +6831,7 @@ const defaultSettings$2 = Object.freeze({
|
|
|
6746
6831
|
},
|
|
6747
6832
|
callback: function (value) {
|
|
6748
6833
|
const label = this.getLabelForValue(value);
|
|
6749
|
-
return ellipsis$1(label,
|
|
6834
|
+
return ellipsis$1(label, chartLabelMaxLength);
|
|
6750
6835
|
}
|
|
6751
6836
|
}
|
|
6752
6837
|
}
|
|
@@ -6874,6 +6959,14 @@ class ContributionChartComponent {
|
|
|
6874
6959
|
* Override the default configuration.
|
|
6875
6960
|
*/
|
|
6876
6961
|
this.config = input({}, ...(ngDevMode ? [{ debugName: "config" }] : []));
|
|
6962
|
+
/**
|
|
6963
|
+
* Tooltip shown when hovering an axis label. Without it the labels are not interactive.
|
|
6964
|
+
*/
|
|
6965
|
+
this.axisTooltipFn = input(...(ngDevMode ? [undefined, { debugName: "axisTooltipFn" }] : []));
|
|
6966
|
+
/**
|
|
6967
|
+
* Called with the index of the axis label that was clicked.
|
|
6968
|
+
*/
|
|
6969
|
+
this.axisLabelClickFn = input(...(ngDevMode ? [undefined, { debugName: "axisLabelClickFn" }] : []));
|
|
6877
6970
|
this.minHeight = input(100, ...(ngDevMode ? [{ debugName: "minHeight" }] : []));
|
|
6878
6971
|
this.maxHeight = input(400, ...(ngDevMode ? [{ debugName: "maxHeight" }] : []));
|
|
6879
6972
|
this.height = input(0, ...(ngDevMode ? [{ debugName: "height" }] : []));
|
|
@@ -6883,6 +6976,10 @@ class ContributionChartComponent {
|
|
|
6883
6976
|
this.category = input(undefined, ...(ngDevMode ? [{ debugName: "category" }] : []));
|
|
6884
6977
|
this.chart = viewChild.required(ChartComponent);
|
|
6885
6978
|
this.tooltip = viewChild.required(ChartTooltipComponent);
|
|
6979
|
+
this.axisTooltip = viewChild('axisTooltip', ...(ngDevMode ? [{ debugName: "axisTooltip" }] : []));
|
|
6980
|
+
this.axisSettings = axisLabelSettings(() => this.axisTooltip(), () => this.axisTooltipFn(), () => this.axisLabelClickFn());
|
|
6981
|
+
this.axisEnabled = computed(() => !!this.axisTooltipFn() || !!this.axisLabelClickFn(), ...(ngDevMode ? [{ debugName: "axisEnabled" }] : []));
|
|
6982
|
+
this.axisTooltipContent = computed(() => (data) => this.axisTooltipFn()?.(data.label, data.index) ?? '', ...(ngDevMode ? [{ debugName: "axisTooltipContent" }] : []));
|
|
6886
6983
|
this.exporting = computed(() => this.chart()?.exporting(), ...(ngDevMode ? [{ debugName: "exporting" }] : []));
|
|
6887
6984
|
this.chartHeight = computed(() => this.height() || chartHeight$1(this.minHeight(), this.maxHeight(), this.labels()?.length ?? 0), ...(ngDevMode ? [{ debugName: "chartHeight" }] : []));
|
|
6888
6985
|
this.hasNegativeContributions = computed(() => this.displayData()?.some(value => value.values.some(v => v < 0)), ...(ngDevMode ? [{ debugName: "hasNegativeContributions" }] : []));
|
|
@@ -6890,6 +6987,7 @@ class ContributionChartComponent {
|
|
|
6890
6987
|
this.defaultConfig = computed(() => ({
|
|
6891
6988
|
options: {
|
|
6892
6989
|
onClick: (event, activeElements, chart) => this.onItemClick(event, activeElements, chart),
|
|
6990
|
+
plugins: { axisHover: this.axisSettings },
|
|
6893
6991
|
scales: {
|
|
6894
6992
|
x: {
|
|
6895
6993
|
display: !this.responsiveService.isMobile(),
|
|
@@ -6912,7 +7010,8 @@ class ContributionChartComponent {
|
|
|
6912
7010
|
afterBarDrawPlugin({
|
|
6913
7011
|
placement: 'right',
|
|
6914
7012
|
textFn: ({ data }) => (isUndefined(data) ? 'No data' : '')
|
|
6915
|
-
})
|
|
7013
|
+
}),
|
|
7014
|
+
...(this.axisEnabled() ? [axisHoverPlugin] : [])
|
|
6916
7015
|
]
|
|
6917
7016
|
}), ...(ngDevMode ? [{ debugName: "defaultConfig" }] : []));
|
|
6918
7017
|
this.dataConfig = computed(() => ({
|
|
@@ -6958,12 +7057,12 @@ class ContributionChartComponent {
|
|
|
6958
7057
|
return downloadFile(this.csvContent(), `${title}-contribution.csv`);
|
|
6959
7058
|
}
|
|
6960
7059
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ContributionChartComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
6961
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: ContributionChartComponent, isStandalone: true, selector: "he-contribution-chart", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, labels: { classPropertyName: "labels", publicName: "labels", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, showExportButton: { classPropertyName: "showExportButton", publicName: "showExportButton", isSignal: true, isRequired: false, transformFunction: null }, showLegend: { classPropertyName: "showLegend", publicName: "showLegend", isSignal: true, isRequired: false, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null }, minHeight: { classPropertyName: "minHeight", publicName: "minHeight", isSignal: true, isRequired: false, transformFunction: null }, maxHeight: { classPropertyName: "maxHeight", publicName: "maxHeight", isSignal: true, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null }, category: { classPropertyName: "category", publicName: "category", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "chart", first: true, predicate: ChartComponent, descendants: true, isSignal: true }, { propertyName: "tooltip", first: true, predicate: ChartTooltipComponent, descendants: true, isSignal: true }], exportAs: ["contributionChart"], ngImport: i0, template: "<div class=\"is-relative\" [class.chart-area-border]=\"showLegend()\">\n <he-chart\n [data]=\"dataConfig()\"\n [config]=\"configuration()\"\n [showExportButton]=\"showExportButton()\"\n [style.height.px]=\"chartHeight()\">\n <he-chart-tooltip [tooltipFn]=\"tooltipFn\" />\n </he-chart>\n\n @if (!data()?.length) {\n <div class=\"is-absolute w-100 h-100 | no-data\">\n <div class=\"is-flex is-justify-content-center is-align-items-center w-100 h-100\">\n <span class=\"is-size-7\">No contribution available.</span>\n </div>\n </div>\n }\n</div>\n\n@if (showLegend()) {\n <he-bar-chart-legend [data]=\"displayData()\" />\n}\n", styles: [":host{display:block}he-chart{height:400px}he-bar-chart-legend ::ng-deep .breakdown-legend--color{border-radius:3px}.no-data{top:0;background-color:#0000004d}\n"], dependencies: [{ kind: "component", type: ChartComponent, selector: "he-chart", inputs: ["data", "config", "showExportButton"], exportAs: ["chart"] }, { kind: "component", type: ChartTooltipComponent, selector: "he-chart-tooltip", inputs: ["tooltipFn"], exportAs: ["chartTooltip"] }, { kind: "component", type: BarChartLegendComponent, selector: "he-bar-chart-legend", inputs: ["data"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
7060
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: ContributionChartComponent, isStandalone: true, selector: "he-contribution-chart", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, labels: { classPropertyName: "labels", publicName: "labels", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, showExportButton: { classPropertyName: "showExportButton", publicName: "showExportButton", isSignal: true, isRequired: false, transformFunction: null }, showLegend: { classPropertyName: "showLegend", publicName: "showLegend", isSignal: true, isRequired: false, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null }, axisTooltipFn: { classPropertyName: "axisTooltipFn", publicName: "axisTooltipFn", isSignal: true, isRequired: false, transformFunction: null }, axisLabelClickFn: { classPropertyName: "axisLabelClickFn", publicName: "axisLabelClickFn", isSignal: true, isRequired: false, transformFunction: null }, minHeight: { classPropertyName: "minHeight", publicName: "minHeight", isSignal: true, isRequired: false, transformFunction: null }, maxHeight: { classPropertyName: "maxHeight", publicName: "maxHeight", isSignal: true, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null }, category: { classPropertyName: "category", publicName: "category", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "chart", first: true, predicate: ChartComponent, descendants: true, isSignal: true }, { propertyName: "tooltip", first: true, predicate: ChartTooltipComponent, descendants: true, isSignal: true }, { propertyName: "axisTooltip", first: true, predicate: ["axisTooltip"], descendants: true, isSignal: true }], exportAs: ["contributionChart"], ngImport: i0, template: "<div class=\"is-relative\" [class.chart-area-border]=\"showLegend()\">\n <he-chart\n [data]=\"dataConfig()\"\n [config]=\"configuration()\"\n [showExportButton]=\"showExportButton()\"\n [style.height.px]=\"chartHeight()\">\n <he-chart-tooltip [tooltipFn]=\"tooltipFn\" />\n @if (axisEnabled()) {\n <he-chart-tooltip #axisTooltip=\"chartTooltip\" [tooltipFn]=\"axisTooltipContent()\" />\n }\n </he-chart>\n\n @if (!data()?.length) {\n <div class=\"is-absolute w-100 h-100 | no-data\">\n <div class=\"is-flex is-justify-content-center is-align-items-center w-100 h-100\">\n <span class=\"is-size-7\">No contribution available.</span>\n </div>\n </div>\n }\n</div>\n\n@if (showLegend()) {\n <he-bar-chart-legend [data]=\"displayData()\" />\n}\n", styles: [":host{display:block}he-chart{height:400px}he-bar-chart-legend ::ng-deep .breakdown-legend--color{border-radius:3px}.no-data{top:0;background-color:#0000004d}\n"], dependencies: [{ kind: "component", type: ChartComponent, selector: "he-chart", inputs: ["data", "config", "showExportButton"], exportAs: ["chart"] }, { kind: "component", type: ChartTooltipComponent, selector: "he-chart-tooltip", inputs: ["tooltipFn"], exportAs: ["chartTooltip"] }, { kind: "component", type: BarChartLegendComponent, selector: "he-bar-chart-legend", inputs: ["data"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
6962
7061
|
}
|
|
6963
7062
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ContributionChartComponent, decorators: [{
|
|
6964
7063
|
type: Component$1,
|
|
6965
|
-
args: [{ selector: 'he-contribution-chart', exportAs: 'contributionChart', changeDetection: ChangeDetectionStrategy.OnPush, imports: [ChartComponent, ChartTooltipComponent, BarChartLegendComponent], template: "<div class=\"is-relative\" [class.chart-area-border]=\"showLegend()\">\n <he-chart\n [data]=\"dataConfig()\"\n [config]=\"configuration()\"\n [showExportButton]=\"showExportButton()\"\n [style.height.px]=\"chartHeight()\">\n <he-chart-tooltip [tooltipFn]=\"tooltipFn\" />\n </he-chart>\n\n @if (!data()?.length) {\n <div class=\"is-absolute w-100 h-100 | no-data\">\n <div class=\"is-flex is-justify-content-center is-align-items-center w-100 h-100\">\n <span class=\"is-size-7\">No contribution available.</span>\n </div>\n </div>\n }\n</div>\n\n@if (showLegend()) {\n <he-bar-chart-legend [data]=\"displayData()\" />\n}\n", styles: [":host{display:block}he-chart{height:400px}he-bar-chart-legend ::ng-deep .breakdown-legend--color{border-radius:3px}.no-data{top:0;background-color:#0000004d}\n"] }]
|
|
6966
|
-
}], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], labels: [{ type: i0.Input, args: [{ isSignal: true, alias: "labels", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], showExportButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "showExportButton", required: false }] }], showLegend: [{ type: i0.Input, args: [{ isSignal: true, alias: "showLegend", required: false }] }], config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: false }] }], minHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "minHeight", required: false }] }], maxHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxHeight", required: false }] }], height: [{ type: i0.Input, args: [{ isSignal: true, alias: "height", required: false }] }], category: [{ type: i0.Input, args: [{ isSignal: true, alias: "category", required: false }] }], chart: [{ type: i0.ViewChild, args: [i0.forwardRef(() => ChartComponent), { isSignal: true }] }], tooltip: [{ type: i0.ViewChild, args: [i0.forwardRef(() => ChartTooltipComponent), { isSignal: true }] }] } });
|
|
7064
|
+
args: [{ selector: 'he-contribution-chart', exportAs: 'contributionChart', changeDetection: ChangeDetectionStrategy.OnPush, imports: [ChartComponent, ChartTooltipComponent, BarChartLegendComponent], template: "<div class=\"is-relative\" [class.chart-area-border]=\"showLegend()\">\n <he-chart\n [data]=\"dataConfig()\"\n [config]=\"configuration()\"\n [showExportButton]=\"showExportButton()\"\n [style.height.px]=\"chartHeight()\">\n <he-chart-tooltip [tooltipFn]=\"tooltipFn\" />\n @if (axisEnabled()) {\n <he-chart-tooltip #axisTooltip=\"chartTooltip\" [tooltipFn]=\"axisTooltipContent()\" />\n }\n </he-chart>\n\n @if (!data()?.length) {\n <div class=\"is-absolute w-100 h-100 | no-data\">\n <div class=\"is-flex is-justify-content-center is-align-items-center w-100 h-100\">\n <span class=\"is-size-7\">No contribution available.</span>\n </div>\n </div>\n }\n</div>\n\n@if (showLegend()) {\n <he-bar-chart-legend [data]=\"displayData()\" />\n}\n", styles: [":host{display:block}he-chart{height:400px}he-bar-chart-legend ::ng-deep .breakdown-legend--color{border-radius:3px}.no-data{top:0;background-color:#0000004d}\n"] }]
|
|
7065
|
+
}], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], labels: [{ type: i0.Input, args: [{ isSignal: true, alias: "labels", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], showExportButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "showExportButton", required: false }] }], showLegend: [{ type: i0.Input, args: [{ isSignal: true, alias: "showLegend", required: false }] }], config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: false }] }], axisTooltipFn: [{ type: i0.Input, args: [{ isSignal: true, alias: "axisTooltipFn", required: false }] }], axisLabelClickFn: [{ type: i0.Input, args: [{ isSignal: true, alias: "axisLabelClickFn", required: false }] }], minHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "minHeight", required: false }] }], maxHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxHeight", required: false }] }], height: [{ type: i0.Input, args: [{ isSignal: true, alias: "height", required: false }] }], category: [{ type: i0.Input, args: [{ isSignal: true, alias: "category", required: false }] }], chart: [{ type: i0.ViewChild, args: [i0.forwardRef(() => ChartComponent), { isSignal: true }] }], tooltip: [{ type: i0.ViewChild, args: [i0.forwardRef(() => ChartTooltipComponent), { isSignal: true }] }], axisTooltip: [{ type: i0.ViewChild, args: ['axisTooltip', { isSignal: true }] }] } });
|
|
6967
7066
|
|
|
6968
7067
|
const colors = {
|
|
6969
7068
|
darkBlue: 'rgba(25, 57, 87, 1)',
|
|
@@ -7423,9 +7522,21 @@ class HorizontalBarChartComponent extends BarChartComponent {
|
|
|
7423
7522
|
super(...arguments);
|
|
7424
7523
|
this.tooltipFn = input(defaultTooltipFn, ...(ngDevMode ? [{ debugName: "tooltipFn" }] : []));
|
|
7425
7524
|
this.afterBarDrawSettings = input(...(ngDevMode ? [undefined, { debugName: "afterBarDrawSettings" }] : []));
|
|
7525
|
+
/**
|
|
7526
|
+
* Tooltip shown when hovering an axis label. Without it the labels are not interactive.
|
|
7527
|
+
*/
|
|
7528
|
+
this.axisTooltipFn = input(...(ngDevMode ? [undefined, { debugName: "axisTooltipFn" }] : []));
|
|
7529
|
+
/**
|
|
7530
|
+
* Called with the index of the axis label that was clicked.
|
|
7531
|
+
*/
|
|
7532
|
+
this.axisLabelClickFn = input(...(ngDevMode ? [undefined, { debugName: "axisLabelClickFn" }] : []));
|
|
7426
7533
|
this.minHeight = input(100, ...(ngDevMode ? [{ debugName: "minHeight" }] : []));
|
|
7427
7534
|
this.maxHeight = input(400, ...(ngDevMode ? [{ debugName: "maxHeight" }] : []));
|
|
7428
7535
|
this.tooltip = viewChild.required(ChartTooltipComponent);
|
|
7536
|
+
this.axisTooltip = viewChild('axisTooltip', ...(ngDevMode ? [{ debugName: "axisTooltip" }] : []));
|
|
7537
|
+
this.axisSettings = axisLabelSettings(() => this.axisTooltip(), () => this.axisTooltipFn(), () => this.axisLabelClickFn());
|
|
7538
|
+
this.axisEnabled = computed(() => !!this.axisTooltipFn() || !!this.axisLabelClickFn(), ...(ngDevMode ? [{ debugName: "axisEnabled" }] : []));
|
|
7539
|
+
this.axisTooltipContent = computed(() => (data) => this.axisTooltipFn()?.(data.label, data.index) ?? '', ...(ngDevMode ? [{ debugName: "axisTooltipContent" }] : []));
|
|
7429
7540
|
this.height = computed(() => chartHeight(this.minHeight(), this.maxHeight(), this.maximumData()?.length ?? 0), ...(ngDevMode ? [{ debugName: "height" }] : []));
|
|
7430
7541
|
this.horizontalConfiguration = computed(() => ({
|
|
7431
7542
|
...merge$1(this.configuration(), defaultConfig, {
|
|
@@ -7435,6 +7546,7 @@ class HorizontalBarChartComponent extends BarChartComponent {
|
|
|
7435
7546
|
const data = this.maximumData()[index];
|
|
7436
7547
|
!isUndefined(index) && this.tooltip().show({ ...data, index }, event.x, event.y, { container: 'body' });
|
|
7437
7548
|
},
|
|
7549
|
+
plugins: { axisHover: this.axisSettings },
|
|
7438
7550
|
scales: {
|
|
7439
7551
|
x: {
|
|
7440
7552
|
grid: {
|
|
@@ -7451,17 +7563,18 @@ class HorizontalBarChartComponent extends BarChartComponent {
|
|
|
7451
7563
|
lollipopChartPlugin(),
|
|
7452
7564
|
backgroundHoverPlugin({ threshold: 5 }),
|
|
7453
7565
|
afterBarDrawPlugin(this.afterBarDrawSettings()),
|
|
7566
|
+
...(this.axisEnabled() ? [axisHoverPlugin] : []),
|
|
7454
7567
|
...(this.configuration().plugins ?? [])
|
|
7455
7568
|
]
|
|
7456
7569
|
}), ...(ngDevMode ? [{ debugName: "horizontalConfiguration" }] : []));
|
|
7457
7570
|
}
|
|
7458
7571
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: HorizontalBarChartComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
7459
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.
|
|
7572
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: HorizontalBarChartComponent, isStandalone: true, selector: "he-horizontal-bar-chart", inputs: { tooltipFn: { classPropertyName: "tooltipFn", publicName: "tooltipFn", isSignal: true, isRequired: false, transformFunction: null }, afterBarDrawSettings: { classPropertyName: "afterBarDrawSettings", publicName: "afterBarDrawSettings", isSignal: true, isRequired: false, transformFunction: null }, axisTooltipFn: { classPropertyName: "axisTooltipFn", publicName: "axisTooltipFn", isSignal: true, isRequired: false, transformFunction: null }, axisLabelClickFn: { classPropertyName: "axisLabelClickFn", publicName: "axisLabelClickFn", isSignal: true, isRequired: false, transformFunction: null }, minHeight: { classPropertyName: "minHeight", publicName: "minHeight", isSignal: true, isRequired: false, transformFunction: null }, maxHeight: { classPropertyName: "maxHeight", publicName: "maxHeight", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "tooltip", first: true, predicate: ChartTooltipComponent, descendants: true, isSignal: true }, { propertyName: "axisTooltip", first: true, predicate: ["axisTooltip"], descendants: true, isSignal: true }], exportAs: ["horizontalBarChart"], usesInheritance: true, ngImport: i0, template: "<div class=\"chart-area-border\">\n <he-chart\n class=\"is-relative h-100\"\n [data]=\"dataConfig()\"\n [config]=\"horizontalConfiguration()\"\n [showExportButton]=\"showExportButton()\"\n [style.height.px]=\"height()\">\n <he-chart-tooltip [tooltipFn]=\"tooltipFn()\" />\n @if (axisEnabled()) {\n <he-chart-tooltip #axisTooltip=\"chartTooltip\" [tooltipFn]=\"axisTooltipContent()\" />\n }\n\n <ng-content />\n </he-chart>\n</div>\n\n<he-bar-chart-legend class=\"is-hidden-tablet\" [data]=\"maximumData()\" />\n", styles: [":host{display:block}\n"], dependencies: [{ kind: "component", type: ChartComponent, selector: "he-chart", inputs: ["data", "config", "showExportButton"], exportAs: ["chart"] }, { kind: "component", type: ChartTooltipComponent, selector: "he-chart-tooltip", inputs: ["tooltipFn"], exportAs: ["chartTooltip"] }, { kind: "component", type: BarChartLegendComponent, selector: "he-bar-chart-legend", inputs: ["data"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
7460
7573
|
}
|
|
7461
7574
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: HorizontalBarChartComponent, decorators: [{
|
|
7462
7575
|
type: Component$1,
|
|
7463
|
-
args: [{ selector: 'he-horizontal-bar-chart', exportAs: 'horizontalBarChart', changeDetection: ChangeDetectionStrategy.OnPush, imports: [ChartComponent, ChartTooltipComponent, BarChartLegendComponent], template: "<div class=\"chart-area-border\">\n <he-chart\n class=\"is-relative h-100\"\n [data]=\"dataConfig()\"\n [config]=\"horizontalConfiguration()\"\n [showExportButton]=\"showExportButton()\"\n [style.height.px]=\"height()\">\n <he-chart-tooltip [tooltipFn]=\"tooltipFn()\" />\n\n <ng-content />\n </he-chart>\n</div>\n\n<he-bar-chart-legend class=\"is-hidden-tablet\" [data]=\"maximumData()\" />\n", styles: [":host{display:block}\n"] }]
|
|
7464
|
-
}], propDecorators: { tooltipFn: [{ type: i0.Input, args: [{ isSignal: true, alias: "tooltipFn", required: false }] }], afterBarDrawSettings: [{ type: i0.Input, args: [{ isSignal: true, alias: "afterBarDrawSettings", required: false }] }], minHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "minHeight", required: false }] }], maxHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxHeight", required: false }] }], tooltip: [{ type: i0.ViewChild, args: [i0.forwardRef(() => ChartTooltipComponent), { isSignal: true }] }] } });
|
|
7576
|
+
args: [{ selector: 'he-horizontal-bar-chart', exportAs: 'horizontalBarChart', changeDetection: ChangeDetectionStrategy.OnPush, imports: [ChartComponent, ChartTooltipComponent, BarChartLegendComponent], template: "<div class=\"chart-area-border\">\n <he-chart\n class=\"is-relative h-100\"\n [data]=\"dataConfig()\"\n [config]=\"horizontalConfiguration()\"\n [showExportButton]=\"showExportButton()\"\n [style.height.px]=\"height()\">\n <he-chart-tooltip [tooltipFn]=\"tooltipFn()\" />\n @if (axisEnabled()) {\n <he-chart-tooltip #axisTooltip=\"chartTooltip\" [tooltipFn]=\"axisTooltipContent()\" />\n }\n\n <ng-content />\n </he-chart>\n</div>\n\n<he-bar-chart-legend class=\"is-hidden-tablet\" [data]=\"maximumData()\" />\n", styles: [":host{display:block}\n"] }]
|
|
7577
|
+
}], propDecorators: { tooltipFn: [{ type: i0.Input, args: [{ isSignal: true, alias: "tooltipFn", required: false }] }], afterBarDrawSettings: [{ type: i0.Input, args: [{ isSignal: true, alias: "afterBarDrawSettings", required: false }] }], axisTooltipFn: [{ type: i0.Input, args: [{ isSignal: true, alias: "axisTooltipFn", required: false }] }], axisLabelClickFn: [{ type: i0.Input, args: [{ isSignal: true, alias: "axisLabelClickFn", required: false }] }], minHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "minHeight", required: false }] }], maxHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxHeight", required: false }] }], tooltip: [{ type: i0.ViewChild, args: [i0.forwardRef(() => ChartTooltipComponent), { isSignal: true }] }], axisTooltip: [{ type: i0.ViewChild, args: ['axisTooltip', { isSignal: true }] }] } });
|
|
7465
7578
|
|
|
7466
7579
|
const primaryProduct = ({ products }) => (products || []).find(({ primary }) => primary);
|
|
7467
7580
|
/**
|
|
@@ -8095,6 +8208,12 @@ const nodeLinkEnabled = (node) => [
|
|
|
8095
8208
|
isExternal() && !!node.id
|
|
8096
8209
|
].some(Boolean)
|
|
8097
8210
|
].every(Boolean);
|
|
8211
|
+
/**
|
|
8212
|
+
* Open a node's page, as `he-node-link` would.
|
|
8213
|
+
*/
|
|
8214
|
+
const openNodeUrl = (node, dataVersion) => nodeLinkEnabled(node)
|
|
8215
|
+
? openUrl([baseUrl(), nodeLink(node, nodeDataState(node), nodeDataVersion(node) || dataVersion)].join('/'), isExternal() ? '_blank' : '_self')
|
|
8216
|
+
: undefined;
|
|
8098
8217
|
var NodeQualityScore;
|
|
8099
8218
|
(function (NodeQualityScore) {
|
|
8100
8219
|
NodeQualityScore["low"] = "Low";
|
|
@@ -9483,11 +9602,11 @@ class FormulaBlockComponent {
|
|
|
9483
9602
|
this.substituted.set(!this.substituted());
|
|
9484
9603
|
}
|
|
9485
9604
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: FormulaBlockComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
9486
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: FormulaBlockComponent, isStandalone: true, selector: "he-formula-block", inputs: { formulas: { classPropertyName: "formulas", publicName: "formulas", isSignal: true, isRequired: false, transformFunction: null }, hasSubstitutions: { classPropertyName: "hasSubstitutions", publicName: "hasSubstitutions", isSignal: true, isRequired: false, transformFunction: null }, emptyTitle: { classPropertyName: "emptyTitle", publicName: "emptyTitle", isSignal: true, isRequired: false, transformFunction: null }, heading: { classPropertyName: "heading", publicName: "heading", isSignal: true, isRequired: false, transformFunction: null }, note: { classPropertyName: "note", publicName: "note", isSignal: true, isRequired: false, transformFunction: null }, showToggle: { classPropertyName: "showToggle", publicName: "showToggle", isSignal: true, isRequired: false, transformFunction: null }, collapsible: { classPropertyName: "collapsible", publicName: "collapsible", isSignal: true, isRequired: false, transformFunction: null }, open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, substituted: { classPropertyName: "substituted", publicName: "substituted", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { open: "openChange", substituted: "substitutedChange" }, ngImport: i0, template: "@if (items().length) {\n <he-collapsible-block [heading]=\"blockHeading()\" [collapsible]=\"collapsible()\" [(open)]=\"open\">\n @if (showToggle()) {\n <div blockActions class=\"field\">\n <input\n type=\"checkbox\"\n class=\"switch is-small is-rounded\"\n [id]=\"toggleId\"\n [checked]=\"substituted()\"\n [disabled]=\"!hasSubstitutions()\"\n (change)=\"toggle()\" />\n <label [for]=\"toggleId\" [title]=\"hasSubstitutions() ? '' : emptyTitle()\">\n <span>{{ substituted() ? 'Substituted' : 'Raw' }}</span>\n </label>\n </div>\n }\n\n <div class=\"formula-block\">\n @if (note()) {\n <p class=\"is-size-8 is-mb-1 | formula-note\">{{ note() }}</p>\n }\n\n @for (item of items(); track $index) {\n @if (item.section) {\n <p class=\"is-size-8 is-uppercase has-text-weight-semibold is-mt-2 | formula-section\">{{ item.section }}</p>\n }\n\n @if (item.contextParts.length) {\n <p class=\"is-size-7 is-mt-1 | formula-context\">\n <ng-container *ngTemplateOutlet=\"textParts; context: { parts: item.contextParts }\" />\n </p>\n }\n\n <div class=\"formula\" [heKatex]=\"item.rendered\"></div>\n\n @if (item.variables.length) {\n <ul class=\"is-size-7 is-mt-1 is-mb-2 is-list-style-disc | formula-variables\">\n @for (variable of item.variables; track $index) {\n <li>\n <div class=\"is-flex is-align-items-baseline is-gap-4\">\n <span class=\"formula-variable-symbol is-nowrap\">\n <span [heKatex]=\"variable.symbol\" [heKatexInline]=\"true\"></span>\n @if (variable.descriptionParts.length) {\n <span>:</span>\n }\n </span>\n @if (variable.descriptionParts.length) {\n <span class=\"is-italic | formula-variable-desc\">\n <ng-container *ngTemplateOutlet=\"textParts; context: { parts: variable.descriptionParts }\" />\n </span>\n }\n @if (variable.note) {\n <span class=\"formula-variable-note\">({{ variable.note }})</span>\n } @else if (variable.missing) {\n <span class=\"has-text-warning\">(missing)</span>\n }\n </div>\n </li>\n }\n </ul>\n }\n }\n </div>\n </he-collapsible-block>\n}\n\n<!-- documentation text: the symbols it names render as math, the rest as markdown -->\n<ng-template #textParts let-parts=\"parts\">\n @for (part of parts; track $index) {\n @if (part.math) {\n <span class=\"formula-inline-math\" [heKatex]=\"part.math\" [heKatexInline]=\"true\"></span>\n } @else {\n <markdown
|
|
9605
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: FormulaBlockComponent, isStandalone: true, selector: "he-formula-block", inputs: { formulas: { classPropertyName: "formulas", publicName: "formulas", isSignal: true, isRequired: false, transformFunction: null }, hasSubstitutions: { classPropertyName: "hasSubstitutions", publicName: "hasSubstitutions", isSignal: true, isRequired: false, transformFunction: null }, emptyTitle: { classPropertyName: "emptyTitle", publicName: "emptyTitle", isSignal: true, isRequired: false, transformFunction: null }, heading: { classPropertyName: "heading", publicName: "heading", isSignal: true, isRequired: false, transformFunction: null }, note: { classPropertyName: "note", publicName: "note", isSignal: true, isRequired: false, transformFunction: null }, showToggle: { classPropertyName: "showToggle", publicName: "showToggle", isSignal: true, isRequired: false, transformFunction: null }, collapsible: { classPropertyName: "collapsible", publicName: "collapsible", isSignal: true, isRequired: false, transformFunction: null }, open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, substituted: { classPropertyName: "substituted", publicName: "substituted", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { open: "openChange", substituted: "substitutedChange" }, ngImport: i0, template: "@if (items().length) {\n <he-collapsible-block [heading]=\"blockHeading()\" [collapsible]=\"collapsible()\" [(open)]=\"open\">\n @if (showToggle()) {\n <div blockActions class=\"field\">\n <input\n type=\"checkbox\"\n class=\"switch is-small is-rounded\"\n [id]=\"toggleId\"\n [checked]=\"substituted()\"\n [disabled]=\"!hasSubstitutions()\"\n (change)=\"toggle()\" />\n <label [for]=\"toggleId\" [title]=\"hasSubstitutions() ? '' : emptyTitle()\">\n <span>{{ substituted() ? 'Substituted' : 'Raw' }}</span>\n </label>\n </div>\n }\n\n <div class=\"formula-block\">\n @if (note()) {\n <p class=\"is-size-8 is-mb-1 | formula-note\">{{ note() }}</p>\n }\n\n @for (item of items(); track $index) {\n @if (item.section) {\n <p class=\"is-size-8 is-uppercase has-text-weight-semibold is-mt-2 | formula-section\">{{ item.section }}</p>\n }\n\n @if (item.contextParts.length) {\n <p class=\"is-size-7 is-mt-1 | formula-context\">\n <ng-container *ngTemplateOutlet=\"textParts; context: { parts: item.contextParts }\" />\n </p>\n }\n\n <div class=\"formula\" [heKatex]=\"item.rendered\"></div>\n\n @if (item.variables.length) {\n <ul class=\"is-size-7 is-mt-1 is-mb-2 is-list-style-disc | formula-variables\">\n @for (variable of item.variables; track $index) {\n <li>\n <div class=\"is-flex is-align-items-baseline is-gap-4\">\n <span class=\"formula-variable-symbol is-nowrap\">\n <span [heKatex]=\"variable.symbol\" [heKatexInline]=\"true\"></span>\n @if (variable.descriptionParts.length) {\n <span>:</span>\n }\n </span>\n @if (variable.descriptionParts.length) {\n <span class=\"is-italic | formula-variable-desc\">\n <ng-container *ngTemplateOutlet=\"textParts; context: { parts: variable.descriptionParts }\" />\n </span>\n }\n @if (variable.note) {\n <span class=\"formula-variable-note\">({{ variable.note }})</span>\n } @else if (variable.missing) {\n <span class=\"has-text-warning\">(missing)</span>\n }\n </div>\n </li>\n }\n </ul>\n }\n }\n </div>\n </he-collapsible-block>\n}\n\n<!-- documentation text: the symbols it names render as math, the rest as markdown -->\n<ng-template #textParts let-parts=\"parts\">\n @for (part of parts; track $index) {\n @if (part.math) {\n <span class=\"formula-inline-math\" [heKatex]=\"part.math\" [heKatexInline]=\"true\"></span>\n } @else {\n <markdown [data]=\"part.text\" />\n }\n }\n</ng-template>\n", styles: [":host{display:block}.formula-section{opacity:.7;letter-spacing:.03em}.formula-note{opacity:.7}.formula-context{opacity:.9}.formula-variables{padding-inline-start:1rem}.formula-variable-symbol{flex-shrink:0}.formula-variable-symbol ::ng-deep .katex{font-size:1em}.formula-variable-desc{opacity:.85}.formula-variable-note{opacity:.7;white-space:nowrap}.formula-context ::ng-deep markdown,.formula-context ::ng-deep markdown *,.formula-variable-desc ::ng-deep markdown,.formula-variable-desc ::ng-deep markdown *{display:inline;margin:0;white-space:pre-wrap}.formula-context .formula-inline-math ::ng-deep .katex,.formula-variable-desc .formula-inline-math ::ng-deep .katex{font-size:1em}.formula{overflow-x:auto;overflow-y:hidden}.formula ::ng-deep .katex-display{margin:.35rem 0}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: KatexDirective, selector: "[heKatex]", inputs: ["heKatex", "heKatexInline"] }, { kind: "component", type: MarkdownComponent, selector: "markdown, [markdown]", inputs: ["data", "src", "disableSanitizer", "inline", "clipboard", "clipboardButtonComponent", "clipboardButtonTemplate", "emoji", "katex", "katexOptions", "mermaid", "mermaidOptions", "lineHighlight", "line", "lineOffset", "lineNumbers", "start", "commandLine", "filterOutput", "host", "prompt", "output", "user"], outputs: ["error", "load", "ready"] }, { kind: "component", type: CollapsibleBlockComponent, selector: "he-collapsible-block", inputs: ["heading", "collapsible", "open"], outputs: ["openChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
9487
9606
|
}
|
|
9488
9607
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: FormulaBlockComponent, decorators: [{
|
|
9489
9608
|
type: Component$1,
|
|
9490
|
-
args: [{ selector: 'he-formula-block', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgTemplateOutlet, KatexDirective, MarkdownComponent, CollapsibleBlockComponent], template: "@if (items().length) {\n <he-collapsible-block [heading]=\"blockHeading()\" [collapsible]=\"collapsible()\" [(open)]=\"open\">\n @if (showToggle()) {\n <div blockActions class=\"field\">\n <input\n type=\"checkbox\"\n class=\"switch is-small is-rounded\"\n [id]=\"toggleId\"\n [checked]=\"substituted()\"\n [disabled]=\"!hasSubstitutions()\"\n (change)=\"toggle()\" />\n <label [for]=\"toggleId\" [title]=\"hasSubstitutions() ? '' : emptyTitle()\">\n <span>{{ substituted() ? 'Substituted' : 'Raw' }}</span>\n </label>\n </div>\n }\n\n <div class=\"formula-block\">\n @if (note()) {\n <p class=\"is-size-8 is-mb-1 | formula-note\">{{ note() }}</p>\n }\n\n @for (item of items(); track $index) {\n @if (item.section) {\n <p class=\"is-size-8 is-uppercase has-text-weight-semibold is-mt-2 | formula-section\">{{ item.section }}</p>\n }\n\n @if (item.contextParts.length) {\n <p class=\"is-size-7 is-mt-1 | formula-context\">\n <ng-container *ngTemplateOutlet=\"textParts; context: { parts: item.contextParts }\" />\n </p>\n }\n\n <div class=\"formula\" [heKatex]=\"item.rendered\"></div>\n\n @if (item.variables.length) {\n <ul class=\"is-size-7 is-mt-1 is-mb-2 is-list-style-disc | formula-variables\">\n @for (variable of item.variables; track $index) {\n <li>\n <div class=\"is-flex is-align-items-baseline is-gap-4\">\n <span class=\"formula-variable-symbol is-nowrap\">\n <span [heKatex]=\"variable.symbol\" [heKatexInline]=\"true\"></span>\n @if (variable.descriptionParts.length) {\n <span>:</span>\n }\n </span>\n @if (variable.descriptionParts.length) {\n <span class=\"is-italic | formula-variable-desc\">\n <ng-container *ngTemplateOutlet=\"textParts; context: { parts: variable.descriptionParts }\" />\n </span>\n }\n @if (variable.note) {\n <span class=\"formula-variable-note\">({{ variable.note }})</span>\n } @else if (variable.missing) {\n <span class=\"has-text-warning\">(missing)</span>\n }\n </div>\n </li>\n }\n </ul>\n }\n }\n </div>\n </he-collapsible-block>\n}\n\n<!-- documentation text: the symbols it names render as math, the rest as markdown -->\n<ng-template #textParts let-parts=\"parts\">\n @for (part of parts; track $index) {\n @if (part.math) {\n <span class=\"formula-inline-math\" [heKatex]=\"part.math\" [heKatexInline]=\"true\"></span>\n } @else {\n <markdown
|
|
9609
|
+
args: [{ selector: 'he-formula-block', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgTemplateOutlet, KatexDirective, MarkdownComponent, CollapsibleBlockComponent], template: "@if (items().length) {\n <he-collapsible-block [heading]=\"blockHeading()\" [collapsible]=\"collapsible()\" [(open)]=\"open\">\n @if (showToggle()) {\n <div blockActions class=\"field\">\n <input\n type=\"checkbox\"\n class=\"switch is-small is-rounded\"\n [id]=\"toggleId\"\n [checked]=\"substituted()\"\n [disabled]=\"!hasSubstitutions()\"\n (change)=\"toggle()\" />\n <label [for]=\"toggleId\" [title]=\"hasSubstitutions() ? '' : emptyTitle()\">\n <span>{{ substituted() ? 'Substituted' : 'Raw' }}</span>\n </label>\n </div>\n }\n\n <div class=\"formula-block\">\n @if (note()) {\n <p class=\"is-size-8 is-mb-1 | formula-note\">{{ note() }}</p>\n }\n\n @for (item of items(); track $index) {\n @if (item.section) {\n <p class=\"is-size-8 is-uppercase has-text-weight-semibold is-mt-2 | formula-section\">{{ item.section }}</p>\n }\n\n @if (item.contextParts.length) {\n <p class=\"is-size-7 is-mt-1 | formula-context\">\n <ng-container *ngTemplateOutlet=\"textParts; context: { parts: item.contextParts }\" />\n </p>\n }\n\n <div class=\"formula\" [heKatex]=\"item.rendered\"></div>\n\n @if (item.variables.length) {\n <ul class=\"is-size-7 is-mt-1 is-mb-2 is-list-style-disc | formula-variables\">\n @for (variable of item.variables; track $index) {\n <li>\n <div class=\"is-flex is-align-items-baseline is-gap-4\">\n <span class=\"formula-variable-symbol is-nowrap\">\n <span [heKatex]=\"variable.symbol\" [heKatexInline]=\"true\"></span>\n @if (variable.descriptionParts.length) {\n <span>:</span>\n }\n </span>\n @if (variable.descriptionParts.length) {\n <span class=\"is-italic | formula-variable-desc\">\n <ng-container *ngTemplateOutlet=\"textParts; context: { parts: variable.descriptionParts }\" />\n </span>\n }\n @if (variable.note) {\n <span class=\"formula-variable-note\">({{ variable.note }})</span>\n } @else if (variable.missing) {\n <span class=\"has-text-warning\">(missing)</span>\n }\n </div>\n </li>\n }\n </ul>\n }\n }\n </div>\n </he-collapsible-block>\n}\n\n<!-- documentation text: the symbols it names render as math, the rest as markdown -->\n<ng-template #textParts let-parts=\"parts\">\n @for (part of parts; track $index) {\n @if (part.math) {\n <span class=\"formula-inline-math\" [heKatex]=\"part.math\" [heKatexInline]=\"true\"></span>\n } @else {\n <markdown [data]=\"part.text\" />\n }\n }\n</ng-template>\n", styles: [":host{display:block}.formula-section{opacity:.7;letter-spacing:.03em}.formula-note{opacity:.7}.formula-context{opacity:.9}.formula-variables{padding-inline-start:1rem}.formula-variable-symbol{flex-shrink:0}.formula-variable-symbol ::ng-deep .katex{font-size:1em}.formula-variable-desc{opacity:.85}.formula-variable-note{opacity:.7;white-space:nowrap}.formula-context ::ng-deep markdown,.formula-context ::ng-deep markdown *,.formula-variable-desc ::ng-deep markdown,.formula-variable-desc ::ng-deep markdown *{display:inline;margin:0;white-space:pre-wrap}.formula-context .formula-inline-math ::ng-deep .katex,.formula-variable-desc .formula-inline-math ::ng-deep .katex{font-size:1em}.formula{overflow-x:auto;overflow-y:hidden}.formula ::ng-deep .katex-display{margin:.35rem 0}\n"] }]
|
|
9491
9610
|
}], propDecorators: { formulas: [{ type: i0.Input, args: [{ isSignal: true, alias: "formulas", required: false }] }], hasSubstitutions: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasSubstitutions", required: false }] }], emptyTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyTitle", required: false }] }], heading: [{ type: i0.Input, args: [{ isSignal: true, alias: "heading", required: false }] }], note: [{ type: i0.Input, args: [{ isSignal: true, alias: "note", required: false }] }], showToggle: [{ type: i0.Input, args: [{ isSignal: true, alias: "showToggle", required: false }] }], collapsible: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsible", required: false }] }], open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }, { type: i0.Output, args: ["openChange"] }], substituted: [{ type: i0.Input, args: [{ isSignal: true, alias: "substituted", required: false }] }, { type: i0.Output, args: ["substitutedChange"] }] } });
|
|
9492
9611
|
|
|
9493
9612
|
const isMissing$1 = (value) => value === undefined || value === null || value === '';
|
|
@@ -10949,7 +11068,6 @@ const methodIdLabel$1 = (methodId) => (methodId
|
|
|
10949
11068
|
const modelKeyLabel = {
|
|
10950
11069
|
'input.hestiaAggregatedData': 'HESTIA aggregated data'
|
|
10951
11070
|
};
|
|
10952
|
-
const termSearch$1 = (term = '') => term.replace(/[,\s]/g, '').toLowerCase();
|
|
10953
11071
|
class NodeJLogModelsComponent {
|
|
10954
11072
|
constructor() {
|
|
10955
11073
|
this.searchService = inject(HeSearchService);
|
|
@@ -11052,7 +11170,7 @@ class NodeJLogModelsComponent {
|
|
|
11052
11170
|
.filter(Boolean), ...(ngDevMode ? [{ debugName: "allTerms" }] : []));
|
|
11053
11171
|
this.enableFilterByTerm = computed(() => this.allTerms().length > 0, ...(ngDevMode ? [{ debugName: "enableFilterByTerm" }] : []));
|
|
11054
11172
|
this.termFormatter = ({ name }) => name;
|
|
11055
|
-
this.suggestTerm = (text$) => text$.pipe(distinctUntilChanged(), map(value => this.allTerms()
|
|
11173
|
+
this.suggestTerm = (text$) => text$.pipe(distinctUntilChanged(), map(value => suggestTerms(this.allTerms(), value)));
|
|
11056
11174
|
this.methodsById = toSignal(this.searchTerms({
|
|
11057
11175
|
bool: { must: [matchType(NodeType.Term), { match: { termType: TermTermType.model } }] }
|
|
11058
11176
|
}).pipe(map(groupTerms$1)));
|
|
@@ -11199,7 +11317,6 @@ const orderBlankNodesByNodeKey = {
|
|
|
11199
11317
|
})), ['methodTierOrder'], ['asc']).map(({ value }) => value)
|
|
11200
11318
|
};
|
|
11201
11319
|
const orderBlankNodes = (blankNodes, nodeKey) => (orderBlankNodesByNodeKey[nodeKey] || (v => v))(blankNodes);
|
|
11202
|
-
const termSearch = (term = '') => term.replace(/[,\s]/g, '').toLowerCase();
|
|
11203
11320
|
const functionalUnit = {
|
|
11204
11321
|
[NodeType.Cycle]: (data) => data.functionalUnit === CycleFunctionalUnit['1 ha'] ? 'hectare' : 'functional unit',
|
|
11205
11322
|
[NodeType.ImpactAssessment]: data => (data.product?.term?.units || data.term?.units) === 'kg'
|
|
@@ -11390,7 +11507,7 @@ class NodeLogsModelsComponent {
|
|
|
11390
11507
|
this.term = signal(undefined, ...(ngDevMode ? [{ debugName: "term" }] : []));
|
|
11391
11508
|
this.enableFilterByTerm = computed(() => this.allTerms()?.length > 0, ...(ngDevMode ? [{ debugName: "enableFilterByTerm" }] : []));
|
|
11392
11509
|
this.termFormatter = ({ name }) => name;
|
|
11393
|
-
this.suggestTerm = (text$) => text$.pipe(distinctUntilChanged(), map(
|
|
11510
|
+
this.suggestTerm = (text$) => text$.pipe(distinctUntilChanged(), map(value => suggestTerms(this.allTerms(), value)));
|
|
11394
11511
|
this.typeaheadFocus = typeaheadFocus;
|
|
11395
11512
|
this.loading = computed(() => [
|
|
11396
11513
|
!this.logsResource.hasValue(),
|
|
@@ -11406,9 +11523,6 @@ class NodeLogsModelsComponent {
|
|
|
11406
11523
|
].some(Boolean), ...(ngDevMode ? [{ debugName: "loading" }] : []));
|
|
11407
11524
|
this.isNumber = (value) => typeof value === 'number';
|
|
11408
11525
|
}
|
|
11409
|
-
suggestByTerm(term) {
|
|
11410
|
-
return this.allTerms().filter(v => termSearch(v.name).includes(termSearch(term)));
|
|
11411
|
-
}
|
|
11412
11526
|
searchTerms(query, ...extraFields) {
|
|
11413
11527
|
return this.searchService
|
|
11414
11528
|
.search$({
|
|
@@ -11579,20 +11693,23 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
|
|
|
11579
11693
|
}], ctorParameters: () => [], propDecorators: { dataState: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataState", required: false }] }], hideIdenticalValues: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideIdenticalValues", required: false }] }] } });
|
|
11580
11694
|
|
|
11581
11695
|
const cycleValue = (cycle, values) => (values[nodeVersionKey(cycle)]?.nodes[0] || { value: [0] }).value;
|
|
11582
|
-
const cycleName = (cycle, index) => `${index + 1}. ${defaultLabel(cycle)}`;
|
|
11583
11696
|
class CyclesEmissionsChartComponent {
|
|
11584
11697
|
constructor() {
|
|
11698
|
+
this.route = inject(ActivatedRoute);
|
|
11585
11699
|
this.cycles = input.required(...(ngDevMode ? [{ debugName: "cycles" }] : []));
|
|
11700
|
+
this.dataVersion = toSignal(this.route.queryParams.pipe(map(({ dataVersion }) => dataVersion)));
|
|
11586
11701
|
this.emissionPerCycle = computed(() => groupNodesByTerm(this.cycles(), 'emissions'), ...(ngDevMode ? [{ debugName: "emissionPerCycle" }] : []));
|
|
11587
11702
|
this.terms = computed(() => Object.values(this.emissionPerCycle() ?? {})
|
|
11588
11703
|
.filter(({ values }) => Object.values(values).some(({ nodes: [{ value }] }) => propertyValue$1(value) > 0))
|
|
11589
11704
|
.map(({ term }) => term)
|
|
11590
11705
|
.sort((a, b) => a.name.localeCompare(b.name)), ...(ngDevMode ? [{ debugName: "terms" }] : []));
|
|
11591
11706
|
this.selectedTerm = signal(undefined, ...(ngDevMode ? [{ debugName: "selectedTerm" }] : []));
|
|
11592
|
-
this.labels = computed(() => this.cycles()
|
|
11707
|
+
this.labels = computed(() => nodeChartLabels(this.cycles(), chartLabelMaxLength), ...(ngDevMode ? [{ debugName: "labels" }] : []));
|
|
11708
|
+
this.axisTooltipFn = (label, index) => this.cycleLabelTooltip(index) || label;
|
|
11709
|
+
this.axisLabelClickFn = index => this.openCycle(index);
|
|
11593
11710
|
this.chartValues = computed(() => this.emissionPerCycle()?.[this.selectedTerm()?.name]?.values || {}, ...(ngDevMode ? [{ debugName: "chartValues" }] : []));
|
|
11594
11711
|
this.chartData = computed(() => this.cycles().map((cycle, index) => ({
|
|
11595
|
-
label:
|
|
11712
|
+
label: this.labels()[index],
|
|
11596
11713
|
count: propertyValue$1(cycleValue(cycle, this.chartValues()), this.selectedTerm?.['@id']),
|
|
11597
11714
|
color: listColor(cycle, index)
|
|
11598
11715
|
})), ...(ngDevMode ? [{ debugName: "chartData" }] : []));
|
|
@@ -11609,12 +11726,20 @@ class CyclesEmissionsChartComponent {
|
|
|
11609
11726
|
const term = this.terms().find(term => term['@id'] === value);
|
|
11610
11727
|
this.selectedTerm.set(term);
|
|
11611
11728
|
}
|
|
11729
|
+
cycleLabelTooltip(index) {
|
|
11730
|
+
const cycle = this.cycles()[index];
|
|
11731
|
+
return cycle ? [`${index + 1}. ${defaultLabel(cycle)}`, cycle['@id']].filter(Boolean).join('<br />') : '';
|
|
11732
|
+
}
|
|
11733
|
+
openCycle(index) {
|
|
11734
|
+
const cycle = this.cycles()[index];
|
|
11735
|
+
return cycle ? openNodeUrl(cycle, this.dataVersion()) : undefined;
|
|
11736
|
+
}
|
|
11612
11737
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: CyclesEmissionsChartComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
11613
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: CyclesEmissionsChartComponent, isStandalone: true, selector: "he-cycles-emissions-chart", inputs: { cycles: { classPropertyName: "cycles", publicName: "cycles", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<div class=\"is-flex is-gap-8 is-justify-content-space-between is-align-items-center is-mb-3\">\n <he-chart-export-button [chart]=\"chart\" [config]=\"{ lollipopConfig: null }\" />\n\n <ng-content />\n</div>\n\n@if (terms().length) {\n <div class=\"field\">\n <div class=\"control is-expanded\">\n <div class=\"select is-small is-fullwidth\">\n <select (change)=\"selectTerm($event)\" id=\"selectTerm\">\n @for (term of terms(); track term) {\n <option [value]=\"term['@id']\">{{ term.name }}</option>\n }\n </select>\n </div>\n </div>\n </div>\n}\n\n<he-horizontal-bar-chart\n #chart=\"horizontalBarChart\"\n class=\"is-relative h-100\"\n [title]=\"selectedTerm()?.units\"\n [data]=\"chartData()\"\n [labels]=\"labels()\"\n [showExportButton]=\"false\" />\n", styles: [":host{display:block;overflow:visible}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "component", type: HorizontalBarChartComponent, selector: "he-horizontal-bar-chart", inputs: ["tooltipFn", "afterBarDrawSettings", "minHeight", "maxHeight"], exportAs: ["horizontalBarChart"] }, { kind: "component", type: ChartExportButtonComponent, selector: "he-chart-export-button", inputs: ["buttonClass", "chart", "config", "exportFormats", "chartExportFn"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
11738
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: CyclesEmissionsChartComponent, isStandalone: true, selector: "he-cycles-emissions-chart", inputs: { cycles: { classPropertyName: "cycles", publicName: "cycles", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<div class=\"is-flex is-gap-8 is-justify-content-space-between is-align-items-center is-mb-3\">\n <he-chart-export-button [chart]=\"chart\" [config]=\"{ lollipopConfig: null }\" />\n\n <ng-content />\n</div>\n\n@if (terms().length) {\n <div class=\"field\">\n <div class=\"control is-expanded\">\n <div class=\"select is-small is-fullwidth\">\n <select (change)=\"selectTerm($event)\" id=\"selectTerm\">\n @for (term of terms(); track term) {\n <option [value]=\"term['@id']\">{{ term.name }}</option>\n }\n </select>\n </div>\n </div>\n </div>\n}\n\n<he-horizontal-bar-chart\n #chart=\"horizontalBarChart\"\n class=\"is-relative h-100\"\n [title]=\"selectedTerm()?.units\"\n [data]=\"chartData()\"\n [labels]=\"labels()\"\n [axisTooltipFn]=\"axisTooltipFn\"\n [axisLabelClickFn]=\"axisLabelClickFn\"\n [showExportButton]=\"false\" />\n", styles: [":host{display:block;overflow:visible}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "component", type: HorizontalBarChartComponent, selector: "he-horizontal-bar-chart", inputs: ["tooltipFn", "afterBarDrawSettings", "axisTooltipFn", "axisLabelClickFn", "minHeight", "maxHeight"], exportAs: ["horizontalBarChart"] }, { kind: "component", type: ChartExportButtonComponent, selector: "he-chart-export-button", inputs: ["buttonClass", "chart", "config", "exportFormats", "chartExportFn"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
11614
11739
|
}
|
|
11615
11740
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: CyclesEmissionsChartComponent, decorators: [{
|
|
11616
11741
|
type: Component$1,
|
|
11617
|
-
args: [{ selector: 'he-cycles-emissions-chart', changeDetection: ChangeDetectionStrategy.OnPush, imports: [FormsModule, HorizontalBarChartComponent, ChartExportButtonComponent], template: "<div class=\"is-flex is-gap-8 is-justify-content-space-between is-align-items-center is-mb-3\">\n <he-chart-export-button [chart]=\"chart\" [config]=\"{ lollipopConfig: null }\" />\n\n <ng-content />\n</div>\n\n@if (terms().length) {\n <div class=\"field\">\n <div class=\"control is-expanded\">\n <div class=\"select is-small is-fullwidth\">\n <select (change)=\"selectTerm($event)\" id=\"selectTerm\">\n @for (term of terms(); track term) {\n <option [value]=\"term['@id']\">{{ term.name }}</option>\n }\n </select>\n </div>\n </div>\n </div>\n}\n\n<he-horizontal-bar-chart\n #chart=\"horizontalBarChart\"\n class=\"is-relative h-100\"\n [title]=\"selectedTerm()?.units\"\n [data]=\"chartData()\"\n [labels]=\"labels()\"\n [showExportButton]=\"false\" />\n", styles: [":host{display:block;overflow:visible}\n"] }]
|
|
11742
|
+
args: [{ selector: 'he-cycles-emissions-chart', changeDetection: ChangeDetectionStrategy.OnPush, imports: [FormsModule, HorizontalBarChartComponent, ChartExportButtonComponent], template: "<div class=\"is-flex is-gap-8 is-justify-content-space-between is-align-items-center is-mb-3\">\n <he-chart-export-button [chart]=\"chart\" [config]=\"{ lollipopConfig: null }\" />\n\n <ng-content />\n</div>\n\n@if (terms().length) {\n <div class=\"field\">\n <div class=\"control is-expanded\">\n <div class=\"select is-small is-fullwidth\">\n <select (change)=\"selectTerm($event)\" id=\"selectTerm\">\n @for (term of terms(); track term) {\n <option [value]=\"term['@id']\">{{ term.name }}</option>\n }\n </select>\n </div>\n </div>\n </div>\n}\n\n<he-horizontal-bar-chart\n #chart=\"horizontalBarChart\"\n class=\"is-relative h-100\"\n [title]=\"selectedTerm()?.units\"\n [data]=\"chartData()\"\n [labels]=\"labels()\"\n [axisTooltipFn]=\"axisTooltipFn\"\n [axisLabelClickFn]=\"axisLabelClickFn\"\n [showExportButton]=\"false\" />\n", styles: [":host{display:block;overflow:visible}\n"] }]
|
|
11618
11743
|
}], ctorParameters: () => [], propDecorators: { cycles: [{ type: i0.Input, args: [{ isSignal: true, alias: "cycles", required: true }] }] } });
|
|
11619
11744
|
|
|
11620
11745
|
class CyclesFunctionalUnitMeasureComponent {
|
|
@@ -12021,9 +12146,7 @@ const distinguishingLabels = (ids) => {
|
|
|
12021
12146
|
*/
|
|
12022
12147
|
const contributorsTable = (values, formulas) => {
|
|
12023
12148
|
const bindings = formulas.flatMap(formula => formula.bindings.filter(isTableBinding));
|
|
12024
|
-
const key = bindings
|
|
12025
|
-
.map(binding => binding.key)
|
|
12026
|
-
.find(name => !isMissing(values[name]) || tableCount(values, name));
|
|
12149
|
+
const key = bindings.map(binding => binding.key).find(name => !isMissing(values[name]) || tableCount(values, name));
|
|
12027
12150
|
if (!key)
|
|
12028
12151
|
return undefined;
|
|
12029
12152
|
const parsed = parseRows(values[key]);
|
|
@@ -12083,7 +12206,6 @@ const inclusionRule = (term, values) => {
|
|
|
12083
12206
|
const fallback = hasLogs(values) ? SKIPPED_RULE : undefined;
|
|
12084
12207
|
return areas.length ? completenessRule(areas) : (termRule(term) ?? fallback);
|
|
12085
12208
|
};
|
|
12086
|
-
|
|
12087
12209
|
// The page every aggregation follows, whatever the product.
|
|
12088
12210
|
const GENERAL_PAGE = 'general-process';
|
|
12089
12211
|
// The product-specific page, by the primary product's `termType`. A term type with no page of its
|
|
@@ -12092,17 +12214,6 @@ const PRODUCT_PAGES = {
|
|
|
12092
12214
|
crop: 'crop',
|
|
12093
12215
|
processedFood: 'processed-food'
|
|
12094
12216
|
};
|
|
12095
|
-
/**
|
|
12096
|
-
* The rules are shown in the order they answer a reader's questions: how this value was calculated,
|
|
12097
|
-
* which Cycles went into it, then how each of those was weighted. Grouping them by what they
|
|
12098
|
-
* compute rather than by the page they are documented on is what puts the two calculations either
|
|
12099
|
-
* side of the contributors they combine.
|
|
12100
|
-
*/
|
|
12101
|
-
const GROUPS = [
|
|
12102
|
-
{ id: 'value', heading: 'How the value is calculated', pageOrder: pages => pages },
|
|
12103
|
-
// a weight is derived by the product's own rules first, then normalised by the general one
|
|
12104
|
-
{ id: 'weights', heading: 'How the weights are calculated', pageOrder: pages => [...pages].reverse() }
|
|
12105
|
-
];
|
|
12106
12217
|
// A symbol worth listing under its formula: it carries documentation the reader needs. Constants
|
|
12107
12218
|
// (e.g. `365`) are self-evident in the formula itself.
|
|
12108
12219
|
const isDocumented = (binding) => !!binding.symbol && !!binding.description;
|
|
@@ -12127,6 +12238,79 @@ const isPlantationWeight = (formula) => bindsTo(formula, 'plantation_lifespan');
|
|
|
12127
12238
|
// The blank node keys whose terms carry a completeness area.
|
|
12128
12239
|
const COMPLETENESS_KEYS = ['products', 'emissions', 'inputs', 'practices'];
|
|
12129
12240
|
const PRODUCTS_KEY = 'products';
|
|
12241
|
+
/**
|
|
12242
|
+
* The rules are shown in the order they answer a reader's questions: how this value was calculated,
|
|
12243
|
+
* which Cycles went into it, then how each of those was weighted. Grouping them by what they
|
|
12244
|
+
* compute rather than by the page they are documented on is what puts the two calculations either
|
|
12245
|
+
* side of the contributors they combine.
|
|
12246
|
+
*/
|
|
12247
|
+
const GROUPS = [
|
|
12248
|
+
{ id: 'value', heading: 'How the value is calculated', pageOrder: pages => pages },
|
|
12249
|
+
// a weight is derived by the product's own rules first, then normalised by the general one
|
|
12250
|
+
{ id: 'weights', heading: 'How the weights are calculated', pageOrder: pages => [...pages].reverse() }
|
|
12251
|
+
];
|
|
12252
|
+
/**
|
|
12253
|
+
* Whether the values were combined by a weighting structure rather than counted equally, which
|
|
12254
|
+
* decides which of the two means is shown. Only `crop` aggregations are split into sub-systems, so
|
|
12255
|
+
* every other product type combines its Cycles unweighted however it was built.
|
|
12256
|
+
*/
|
|
12257
|
+
const isWeightedAggregation = ({ termType, termId, worldAggregation, subAggregation }) => !!worldAggregation || isPlantation(termId ?? '') || (termType === TermTermType.crop && !subAggregation);
|
|
12258
|
+
/**
|
|
12259
|
+
* The pages whose formulas are shown: the general rules, then the product-specific ones.
|
|
12260
|
+
*/
|
|
12261
|
+
const aggregationPages = (termType) => {
|
|
12262
|
+
const productPage = PRODUCT_PAGES[termType ?? ''];
|
|
12263
|
+
return [GENERAL_PAGE, ...(productPage ? [productPage] : [])];
|
|
12264
|
+
};
|
|
12265
|
+
/**
|
|
12266
|
+
* Whether the rule ran for this aggregation at all. Some stages depend on what was aggregated
|
|
12267
|
+
* rather than on the data item shown: the production-share weighting only combines countries into
|
|
12268
|
+
* a World aggregation, and the phase weighting only splits the lifespan of a plantation crop.
|
|
12269
|
+
*/
|
|
12270
|
+
const ranForAggregation = (rules) => (formula) => {
|
|
12271
|
+
// the stages that only run for some aggregations, and whether each ran for this one. A formula
|
|
12272
|
+
// matching none of them is part of every aggregation.
|
|
12273
|
+
const stages = [
|
|
12274
|
+
{ applies: isWorldWeight, ran: () => !!rules.worldAggregation },
|
|
12275
|
+
{ applies: isSubSystemWeight, ran: () => !!rules.subAggregation },
|
|
12276
|
+
{ applies: isPlantationWeight, ran: () => isPlantation(rules.termId ?? '') },
|
|
12277
|
+
{ applies: isWeightNormalisation, ran: () => isWeightedAggregation(rules) }
|
|
12278
|
+
];
|
|
12279
|
+
return stages.find(({ applies }) => applies(formula))?.ran() ?? true;
|
|
12280
|
+
};
|
|
12281
|
+
/**
|
|
12282
|
+
* Whether the rule applies to the kind of data item shown. With no `nodeKey` every rule is kept,
|
|
12283
|
+
* which is the whole-aggregation view.
|
|
12284
|
+
*/
|
|
12285
|
+
const appliesToNodeKey = (nodeKey) => (formula) => {
|
|
12286
|
+
if (!nodeKey)
|
|
12287
|
+
return true;
|
|
12288
|
+
if (isEconomicValueShare(formula))
|
|
12289
|
+
return nodeKey === PRODUCTS_KEY;
|
|
12290
|
+
if (isCompletenessZeroFill(formula))
|
|
12291
|
+
return COMPLETENESS_KEYS.includes(nodeKey);
|
|
12292
|
+
return true;
|
|
12293
|
+
};
|
|
12294
|
+
const appliesToAggregation = (rules) => (formula) => ranForAggregation(rules)(formula) &&
|
|
12295
|
+
appliesToNodeKey(rules.nodeKey)(formula) &&
|
|
12296
|
+
isMeanThatRan(formula, isWeightedAggregation(rules));
|
|
12297
|
+
/**
|
|
12298
|
+
* Empty when the documentation carries no rule that applies: `@hestia-earth/aggregation-engine`
|
|
12299
|
+
* before 0.23.5 documents only the weighted mean, so an unweighted aggregation matches nothing.
|
|
12300
|
+
* `pageFormulas` is how it is read - a build resolves the package's JSON module, a test does not.
|
|
12301
|
+
*/
|
|
12302
|
+
const aggregationSections = (rules, pageFormulas = getFormulas$1) => {
|
|
12303
|
+
const applies = appliesToAggregation(rules);
|
|
12304
|
+
return GROUPS.map(({ id, heading, pageOrder }) => ({
|
|
12305
|
+
id,
|
|
12306
|
+
heading,
|
|
12307
|
+
formulas: pageOrder(aggregationPages(rules.termType))
|
|
12308
|
+
.flatMap(page => pageFormulas(page))
|
|
12309
|
+
.filter(formula => formulaGroup(formula) === id && applies(formula))
|
|
12310
|
+
})).filter(section => section.formulas.length > 0);
|
|
12311
|
+
};
|
|
12312
|
+
const documentedBindings = (formula) => formula.bindings.filter(isDocumented);
|
|
12313
|
+
|
|
12130
12314
|
class NodeAggregatedFormulasComponent {
|
|
12131
12315
|
constructor() {
|
|
12132
12316
|
/**
|
|
@@ -12170,20 +12354,15 @@ class NodeAggregatedFormulasComponent {
|
|
|
12170
12354
|
// show the substituted formula rather than the symbolic one, when there is anything to substitute
|
|
12171
12355
|
this.substituted = model(false, ...(ngDevMode ? [{ debugName: "substituted" }] : []));
|
|
12172
12356
|
/**
|
|
12173
|
-
* The
|
|
12174
|
-
*/
|
|
12175
|
-
this.pages = computed(() => {
|
|
12176
|
-
const productPage = PRODUCT_PAGES[this.termType() ?? ''];
|
|
12177
|
-
return [GENERAL_PAGE, ...(productPage ? [productPage] : [])];
|
|
12178
|
-
}, ...(ngDevMode ? [{ debugName: "pages" }] : []));
|
|
12179
|
-
/**
|
|
12180
|
-
* Whether the values were combined by a weighting structure rather than counted equally, which
|
|
12181
|
-
* decides which of the two means is shown. Only `crop` aggregations are split into sub-systems, so
|
|
12182
|
-
* every other product type combines its Cycles unweighted however it was built.
|
|
12357
|
+
* The rules that produced this value, grouped by what each one computes.
|
|
12183
12358
|
*/
|
|
12184
|
-
this.
|
|
12185
|
-
|
|
12186
|
-
|
|
12359
|
+
this.sections = computed(() => aggregationSections({
|
|
12360
|
+
termType: this.termType(),
|
|
12361
|
+
termId: this.termId(),
|
|
12362
|
+
nodeKey: this.nodeKey(),
|
|
12363
|
+
worldAggregation: this.worldAggregation(),
|
|
12364
|
+
subAggregation: this.subAggregation()
|
|
12365
|
+
}), ...(ngDevMode ? [{ debugName: "sections" }] : []));
|
|
12187
12366
|
this.inclusion = computed(() => inclusionRule(this.term(), this.values()), ...(ngDevMode ? [{ debugName: "inclusion" }] : []));
|
|
12188
12367
|
// whether any symbol actually resolves; when none does, the substituted view would be identical
|
|
12189
12368
|
// to the symbolic one, so the toggle is disabled rather than silently doing nothing
|
|
@@ -12191,16 +12370,6 @@ class NodeAggregatedFormulasComponent {
|
|
|
12191
12370
|
const values = this.values();
|
|
12192
12371
|
return this.sections().some(section => section.formulas.some(formula => hasAnySubstitution(values, formula.bindings)));
|
|
12193
12372
|
}, ...(ngDevMode ? [{ debugName: "hasSubstitutions" }] : []));
|
|
12194
|
-
/**
|
|
12195
|
-
* The rules that produced this value, grouped by what each one computes.
|
|
12196
|
-
*/
|
|
12197
|
-
this.sections = computed(() => GROUPS.map(({ id, heading, pageOrder }) => ({
|
|
12198
|
-
id,
|
|
12199
|
-
heading,
|
|
12200
|
-
formulas: pageOrder(this.pages())
|
|
12201
|
-
.flatMap(page => getFormulas$1(page))
|
|
12202
|
-
.filter(formula => formulaGroup(formula) === id && this.applies(formula))
|
|
12203
|
-
})).filter(section => section.formulas.length > 0), ...(ngDevMode ? [{ debugName: "sections" }] : []));
|
|
12204
12373
|
/**
|
|
12205
12374
|
* What this value was combined from, as the aggregation recorded it: one row per contributor,
|
|
12206
12375
|
* under the symbols the formulas above read them with. Absent where the contributors were too
|
|
@@ -12232,7 +12401,7 @@ class NodeAggregatedFormulasComponent {
|
|
|
12232
12401
|
// this formula was extracted from - so the panel explains it in the documentation's words
|
|
12233
12402
|
section: formula.section,
|
|
12234
12403
|
context: formula.context,
|
|
12235
|
-
variables: formula
|
|
12404
|
+
variables: documentedBindings(formula).map(binding => ({
|
|
12236
12405
|
symbol: binding.symbol,
|
|
12237
12406
|
description: binding.description,
|
|
12238
12407
|
// only an input that should have resolved is flagged - a constant, or a quantity the
|
|
@@ -12247,41 +12416,6 @@ class NodeAggregatedFormulasComponent {
|
|
|
12247
12416
|
}));
|
|
12248
12417
|
}, ...(ngDevMode ? [{ debugName: "renderedSections" }] : []));
|
|
12249
12418
|
}
|
|
12250
|
-
/**
|
|
12251
|
-
* Whether the rule ran for this aggregation at all. Some stages depend on what was aggregated
|
|
12252
|
-
* rather than on the data item shown: the production-share weighting only combines countries into
|
|
12253
|
-
* a World aggregation, and the phase weighting only splits the lifespan of a plantation crop.
|
|
12254
|
-
*/
|
|
12255
|
-
ranForAggregation(formula) {
|
|
12256
|
-
// the stages that only run for some aggregations, and whether each ran for this one. A formula
|
|
12257
|
-
// matching none of them is part of every aggregation.
|
|
12258
|
-
const stages = [
|
|
12259
|
-
{ applies: isWorldWeight, ran: () => this.worldAggregation() },
|
|
12260
|
-
{ applies: isSubSystemWeight, ran: () => this.subAggregation() },
|
|
12261
|
-
{ applies: isPlantationWeight, ran: () => isPlantation(this.termId() ?? '') },
|
|
12262
|
-
{ applies: isWeightNormalisation, ran: () => this.weighted() }
|
|
12263
|
-
];
|
|
12264
|
-
return stages.find(({ applies }) => applies(formula))?.ran() ?? true;
|
|
12265
|
-
}
|
|
12266
|
-
/**
|
|
12267
|
-
* Whether the rule applies to the kind of data item shown. With no `nodeKey` every rule is kept,
|
|
12268
|
-
* which is the whole-aggregation view.
|
|
12269
|
-
*/
|
|
12270
|
-
appliesToNodeKey(formula) {
|
|
12271
|
-
const nodeKey = this.nodeKey();
|
|
12272
|
-
if (!nodeKey)
|
|
12273
|
-
return true;
|
|
12274
|
-
if (isEconomicValueShare(formula))
|
|
12275
|
-
return nodeKey === PRODUCTS_KEY;
|
|
12276
|
-
if (isCompletenessZeroFill(formula))
|
|
12277
|
-
return COMPLETENESS_KEYS.includes(nodeKey);
|
|
12278
|
-
return true;
|
|
12279
|
-
}
|
|
12280
|
-
applies(formula) {
|
|
12281
|
-
return (this.ranForAggregation(formula) &&
|
|
12282
|
-
this.appliesToNodeKey(formula) &&
|
|
12283
|
-
isMeanThatRan(formula, this.weighted()));
|
|
12284
|
-
}
|
|
12285
12419
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NodeAggregatedFormulasComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
12286
12420
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: NodeAggregatedFormulasComponent, isStandalone: true, selector: "he-node-aggregated-formulas", inputs: { termType: { classPropertyName: "termType", publicName: "termType", isSignal: true, isRequired: false, transformFunction: null }, termId: { classPropertyName: "termId", publicName: "termId", isSignal: true, isRequired: false, transformFunction: null }, nodeKey: { classPropertyName: "nodeKey", publicName: "nodeKey", isSignal: true, isRequired: false, transformFunction: null }, term: { classPropertyName: "term", publicName: "term", isSignal: true, isRequired: false, transformFunction: null }, values: { classPropertyName: "values", publicName: "values", isSignal: true, isRequired: false, transformFunction: null }, worldAggregation: { classPropertyName: "worldAggregation", publicName: "worldAggregation", isSignal: true, isRequired: false, transformFunction: null }, subAggregation: { classPropertyName: "subAggregation", publicName: "subAggregation", isSignal: true, isRequired: false, transformFunction: null }, substituted: { classPropertyName: "substituted", publicName: "substituted", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { substituted: "substitutedChange" }, ngImport: i0, template: "@if (renderedSections().length) {\n <div class=\"aggregated-formulas\">\n <p class=\"is-size-7 is-mb-2 | formula-intro\">\n Aggregated values are calculated from the underlying {{ contributor().group }}, not measured. These are the rules\n that produced this one, in the order they are applied.\n </p>\n\n <div class=\"is-pt-2 is-pr-1 is-overflow-y-auto | aggregated-formulas-rules\">\n <!-- what went in, before the rules that combine it: the formulas cannot show this -->\n @if (inclusion(); as rule) {\n <he-collapsible-block heading=\"Which Cycles are included\">\n <p class=\"is-size-7\">{{ rule.included }}</p>\n <p class=\"is-size-7\">{{ rule.blank }}</p>\n </he-collapsible-block>\n }\n\n @for (section of renderedSections(); track section.id; let first = $first) {\n <he-formula-block\n [formulas]=\"section.formulas\"\n [heading]=\"section.heading\"\n [collapsible]=\"true\"\n [showToggle]=\"first\"\n [hasSubstitutions]=\"hasSubstitutions()\"\n [(substituted)]=\"substituted\"\n emptyTitle=\"No recorded values to substitute\" />\n\n <!-- the contributors sit between the two calculations: what went in, above how a weight is derived -->\n @if (section.id === 'value' && contributors(); as table) {\n <he-collapsible-block [heading]=\"contributor().heading\">\n @if (table.rows.length) {\n <table class=\"table is-narrow is-size-7 w-100 | contributors-table\">\n <thead>\n <tr>\n <th>{{ contributor().row }}</th>\n @for (column of table.columns; track column.symbol) {\n <th class=\"has-text-right\">\n <span [heKatex]=\"column.symbol\" [heKatexInline]=\"true\"></span>\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @for (row of table.rows; track row.id) {\n <tr>\n <td [attr.title]=\"row.id\">\n <he-node-link [node]=\"row.node\" linkClass=\"has-text-white\">\n <span class=\"break-word\">{{ row.label }}</span>\n </he-node-link>\n </td>\n @for (value of row.values; track $index) {\n <td class=\"has-text-right is-nowrap\">{{ value | precision: 4 | default: '-' }}</td>\n }\n </tr>\n }\n </tbody>\n </table>\n } @else {\n <p class=\"is-size-7\">\n Combined from {{ table.count }} {{ contributor().group }}, too many for the aggregation to record one by\n one.\n </p>\n }\n </he-collapsible-block>\n }\n }\n </div>\n </div>\n}\n", styles: [".formula-intro{opacity:.85}.contributors-table{background-color:transparent;color:inherit}.contributors-table th,.contributors-table td{border-color:#fff3;color:inherit;padding:.15rem .5rem .15rem 0;vertical-align:top}.contributors-table th{opacity:.7}.contributors-table ::ng-deep .katex{font-size:1em}.aggregated-formulas-rules{max-height:50vh}\n"], dependencies: [{ kind: "directive", type: KatexDirective, selector: "[heKatex]", inputs: ["heKatex", "heKatexInline"] }, { kind: "component", type: NodeLinkComponent, selector: "he-node-link", inputs: ["node", "dataState", "showExternalLink", "linkClass"] }, { kind: "component", type: FormulaBlockComponent, selector: "he-formula-block", inputs: ["formulas", "hasSubstitutions", "emptyTitle", "heading", "note", "showToggle", "collapsible", "open", "substituted"], outputs: ["openChange", "substitutedChange"] }, { kind: "component", type: CollapsibleBlockComponent, selector: "he-collapsible-block", inputs: ["heading", "collapsible", "open"], outputs: ["openChange"] }, { kind: "pipe", type: DefaultPipe, name: "default" }, { kind: "pipe", type: PrecisionPipe, name: "precision" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
12287
12421
|
}
|
|
@@ -12530,7 +12664,7 @@ class NodeAggregationLogsComponent {
|
|
|
12530
12664
|
* entries for one term (e.g. a measurement at two depths) collapse into one expandable group whose
|
|
12531
12665
|
* rows are labelled by what tells them apart.
|
|
12532
12666
|
*/
|
|
12533
|
-
this.
|
|
12667
|
+
this.allGroups = computed(() => {
|
|
12534
12668
|
const blankNodes = (this.node()?.[this.nodeKey()] ?? []);
|
|
12535
12669
|
const logs = this.scopedJlog()?.[this.nodeKey()] ?? {};
|
|
12536
12670
|
const open = this.openGroups();
|
|
@@ -12547,6 +12681,33 @@ class NodeAggregationLogsComponent {
|
|
|
12547
12681
|
}));
|
|
12548
12682
|
return { ...group, rows, isOpen: open.has(group.termId), observations: groupObservations(rows) };
|
|
12549
12683
|
});
|
|
12684
|
+
}, ...(ngDevMode ? [{ debugName: "allGroups" }] : []));
|
|
12685
|
+
/**
|
|
12686
|
+
* The rules that produced these values, which the row's `Logs` panel shows. They are read from the
|
|
12687
|
+
* documentation shipped by `@hestia-earth/aggregation-engine`, so an older copy of it can document
|
|
12688
|
+
* none that apply to this aggregation - and the panel would then open on nothing.
|
|
12689
|
+
*/
|
|
12690
|
+
this.hasRules = computed(() => aggregationSections({
|
|
12691
|
+
termType: this.termType(),
|
|
12692
|
+
termId: this.termId(),
|
|
12693
|
+
nodeKey: this.nodeKey(),
|
|
12694
|
+
worldAggregation: this.worldAggregation(),
|
|
12695
|
+
subAggregation: this.subAggregation()
|
|
12696
|
+
}).length > 0, ...(ngDevMode ? [{ debugName: "hasRules" }] : []));
|
|
12697
|
+
// filter the list of results by a single Term, as the recalculation logs do
|
|
12698
|
+
this.term = signal(undefined, ...(ngDevMode ? [{ debugName: "term" }] : []));
|
|
12699
|
+
this.typeaheadFocus = typeaheadFocus;
|
|
12700
|
+
this.allTerms = computed(() => this.allGroups()
|
|
12701
|
+
.map(({ term }) => term)
|
|
12702
|
+
.filter(Boolean), ...(ngDevMode ? [{ debugName: "allTerms" }] : []));
|
|
12703
|
+
this.enableFilterByTerm = computed(() => this.allTerms().length > 0, ...(ngDevMode ? [{ debugName: "enableFilterByTerm" }] : []));
|
|
12704
|
+
this.termFormatter = ({ name }) => name;
|
|
12705
|
+
this.suggestTerm = (text$) => text$.pipe(distinctUntilChanged(), map(value => suggestTerms(this.allTerms(), value)));
|
|
12706
|
+
this.groups = computed(() => {
|
|
12707
|
+
const selected = this.term();
|
|
12708
|
+
return selected
|
|
12709
|
+
? this.allGroups().filter(({ term }) => term?.name?.toLowerCase().includes(selected.name.toLowerCase()))
|
|
12710
|
+
: this.allGroups();
|
|
12550
12711
|
}, ...(ngDevMode ? [{ debugName: "groups" }] : []));
|
|
12551
12712
|
}
|
|
12552
12713
|
toggleGroup(group) {
|
|
@@ -12563,13 +12724,15 @@ class NodeAggregationLogsComponent {
|
|
|
12563
12724
|
return `${row.index}-${row.label}`;
|
|
12564
12725
|
}
|
|
12565
12726
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NodeAggregationLogsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
12566
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: NodeAggregationLogsComponent, isStandalone: true, selector: "he-node-aggregation-logs", inputs: { node: { classPropertyName: "node", publicName: "node", isSignal: true, isRequired: false, transformFunction: null }, nodeKey: { classPropertyName: "nodeKey", publicName: "nodeKey", isSignal: true, isRequired: false, transformFunction: null }, termType: { classPropertyName: "termType", publicName: "termType", isSignal: true, isRequired: false, transformFunction: null }, termId: { classPropertyName: "termId", publicName: "termId", isSignal: true, isRequired: false, transformFunction: null }, jlogParentKey: { classPropertyName: "jlogParentKey", publicName: "jlogParentKey", isSignal: true, isRequired: false, transformFunction: null }, jlogParentIndex: { classPropertyName: "jlogParentIndex", publicName: "jlogParentIndex", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"is-flex is-gap-8 is-justify-content-space-between is-align-items-center is-my-2\">\n <div>\n <ng-content />\n </div>\n</div>\n\n<he-data-table class=\"is-mt-2 is-mb-1 is-bordered\" [small]=\"true\" maxHeight=\"320\">\n <table class=\"table is-fullwidth is-narrow is-striped\">\n <thead>\n <tr>\n <th class=\"width-auto has-border-right\"></th>\n <th class=\"has-border-right\"><span>Units</span></th>\n <th class=\"has-border-right\"><span>Aggregated</span></th>\n <th class=\"has-border-right\">\n <span title=\"The number of Cycles the value was aggregated from\">Observations</span>\n </th>\n <th class=\"has-border-right\"><span>Model</span></th>\n </tr>\n </thead>\n <tbody>\n @if (groups().length === 0) {\n <tr>\n <td class=\"has-border-right has-text-centered\" colspan=\"100\">\n <p class=\"is-p-1\">No aggregated data to show.</p>\n </td>\n </tr>\n }\n @for (group of groups(); track trackByGroup($index, group)) {\n @let single = group.rows.length === 1;\n <tr [class.has-sub-rows]=\"group.canOpen\" [class.is-open]=\"group.isOpen\">\n <td class=\"width-auto has-border-right is-nowrap\" [attr.title]=\"group.term?.name\">\n <div class=\"is-flex is-align-items-flex-start is-gap-4\">\n @if (group.canOpen) {\n <a class=\"open-node\" (click)=\"toggleGroup(group)\">\n <he-svg-icon [name]=\"group.isOpen ? 'chevron-down' : 'chevron-right'\" />\n </a>\n }\n <he-node-link class=\"is-inline-block is-pre-wrap is-pr-2\" [node]=\"group.term\">\n <span class=\"break-word\" [innerHtml]=\"group.term?.name | compound: group.term?.termType\"></span>\n </he-node-link>\n </div>\n </td>\n\n @if (single) {\n <ng-container *ngTemplateOutlet=\"valueCells; context: { row: group.rows[0], term: group.term }\" />\n <ng-container *ngTemplateOutlet=\"modelCell; context: { row: group.rows[0] }\" />\n } @else {\n <td class=\"has-border-right\">\n <span class=\"is-nowrap\" [innerHtml]=\"group.term?.units | compound\"></span>\n </td>\n <td class=\"has-border-right is-nowrap\">\n @if (group.valueFormula) {\n <span\n class=\"has-formula\"\n [ngbPopover]=\"group.valueFormula\"\n popoverClass=\"is-narrow\"\n triggers=\"click\"\n container=\"body\">\n {{ group.value | precision: 3 | default: '-' }}\n </span>\n } @else {\n {{ group.value | precision: 3 | default: '-' }}\n }\n </td>\n <td class=\"has-border-right is-nowrap\">{{ group.observations | default: '-' }}</td>\n <ng-container *ngTemplateOutlet=\"modelCell\" />\n }\n </tr>\n\n @if (!single && group.isOpen) {\n @for (row of group.rows; track trackByRow($index, row)) {\n <tr class=\"is-sub-row\">\n <td class=\"width-auto has-border-right\">\n <div class=\"is-flex is-align-items-flex-start is-gap-4 is-pl-3\">\n <he-svg-icon class=\"sub-sub-row-icon\" name=\"chevron-double-right\" />\n <he-blank-node-identity\n [segments]=\"row.segments\"\n [scalars]=\"row.scalars\"\n [type]=\"group.type\"\n [fallback]=\"'entry ' + (row.index + 1)\" />\n </div>\n </td>\n <ng-container *ngTemplateOutlet=\"valueCells; context: { row, term: group.term }\" />\n <ng-container *ngTemplateOutlet=\"modelCell; context: { row }\" />\n </tr>\n }\n }\n }\n </tbody>\n </table>\n</he-data-table>\n\n<ng-template #valueCells let-row=\"row\" let-term=\"term\">\n <td class=\"has-border-right\">\n <span class=\"is-nowrap\" [innerHtml]=\"term?.units | compound\"></span>\n </td>\n <td class=\"has-border-right is-nowrap\">\n {{ row.displayValue | precision: 3 | default: '-' }}\n </td>\n <td class=\"has-border-right is-nowrap\">\n {{ row.observations | default: '-' }}\n </td>\n</ng-template>\n\n<!-- `row` is left out on a term group: the rules are the same for every entry it holds, so the guide\n is shown there too, but the values to substitute belong to one entry - those stay on the sub-rows -->\n<ng-template #modelCell let-row=\"row\">\n <td class=\"has-border-right\">\n <div class=\"is-flex is-align-self-stretch is-align-items-center is-gap-8\">\n <span class=\"is-flex-grow-1 is-nowrap\">{{ modelName }}</span>\n\n <div class=\"is-flex is-gap-4 is-flex-shrink-0 is-align-items-center\">\n @if (row) {\n <span\n class=\"is-nowrap is-clickable\"\n [ngbPopover]=\"aggregationRules\"\n autoClose=\"outside\"\n popoverClass=\"is-narrow\"\n triggers=\"manual\"\n #p=\"ngbPopover\"\n placement=\"bottom left right auto\"\n container=\"body\"\n (click)=\"p.isOpen() ? p.close() : p.open({ values: row.values, term: row.term })\">\n <span class=\"has-text-link\">Logs</span>\n </span>\n } @else {\n <span class=\"has-text-grey is-nowrap\">Expand for logs</span>\n }\n\n <div class=\"vertical-divider\"></div>\n\n @if (guideEnabled) {\n <he-guide-overlay [pageId]=\"guidePage()\" [width]=\"500\" />\n } @else {\n <a [href]=\"guideHref()\" target=\"_blank\" rel=\"noopener\" (click)=\"$event.stopPropagation()\">\n <span>Docs</span>\n <he-svg-icon name=\"external-link\" class=\"ml-2\" />\n </a>\n }\n </div>\n </div>\n </td>\n</ng-template>\n\n<ng-template #aggregationRules let-values=\"values\" let-term=\"term\">\n <he-node-aggregated-formulas\n [termType]=\"termType()\"\n [termId]=\"termId()\"\n [nodeKey]=\"nodeKey()\"\n [term]=\"term\"\n [values]=\"values\"\n [worldAggregation]=\"worldAggregation()\"\n [subAggregation]=\"subAggregation()\" />\n</ng-template>\n", styles: [":host{display:block}:host .vertical-divider{width:1px;height:20px;background:#dbe3ea}:host .has-formula{cursor:help;border-bottom:1px dotted currentColor}::ng-deep .table{background-color:transparent}::ng-deep .table td.has-border-right{box-shadow:1px 0 #4c7194}::ng-deep .table td>div{min-height:24px}::ng-deep .table .has-sub-rows.is-open>td:first-child:before,::ng-deep .table .is-sub-row>td:first-child:before{display:block;position:absolute;content:\" \";background-color:#4c719433;height:100%;width:1px;top:0;left:14px}::ng-deep .table .has-sub-rows.is-open>td:first-child:before{top:25px}::ng-deep .table .is-sub-row .open-node>he-svg-icon,::ng-deep .table .is-sub-row .sub-sub-row-icon{height:16px!important;width:16px!important}::ng-deep .table .is-sub-sub-row td:first-child{padding-left:24px}::ng-deep .table th:last-child,::ng-deep .table td:last-child{min-width:12rem}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: NgbPopover, selector: "[ngbPopover]", inputs: ["animation", "autoClose", "ngbPopover", "popoverTitle", "placement", "popperOptions", "triggers", "positionTarget", "container", "disablePopover", "popoverClass", "popoverContext", "openDelay", "closeDelay"], outputs: ["shown", "hidden"], exportAs: ["ngbPopover"] }, { kind: "component", type: DataTableComponent, selector: "he-data-table", inputs: ["minHeight", "maxHeight", "small"] }, { kind: "component", type: HESvgIconComponent, selector: "he-svg-icon", inputs: ["name", "size", "animation"] }, { kind: "component", type: NodeLinkComponent, selector: "he-node-link", inputs: ["node", "dataState", "showExternalLink", "linkClass"] }, { kind: "component", type: BlankNodeIdentityComponent, selector: "he-blank-node-identity", inputs: ["segments", "scalars", "type", "fallback"] }, { kind: "component", type: GuideOverlayComponent, selector: "he-guide-overlay", inputs: ["pageId", "width", "height", "positions"], outputs: ["widthChange", "heightChange"] }, { kind: "component", type: NodeAggregatedFormulasComponent, selector: "he-node-aggregated-formulas", inputs: ["termType", "termId", "nodeKey", "term", "values", "worldAggregation", "subAggregation", "substituted"], outputs: ["substitutedChange"] }, { kind: "pipe", type: CompoundPipe, name: "compound" }, { kind: "pipe", type: DefaultPipe, name: "default" }, { kind: "pipe", type: PrecisionPipe, name: "precision" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
12727
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: NodeAggregationLogsComponent, isStandalone: true, selector: "he-node-aggregation-logs", inputs: { node: { classPropertyName: "node", publicName: "node", isSignal: true, isRequired: false, transformFunction: null }, nodeKey: { classPropertyName: "nodeKey", publicName: "nodeKey", isSignal: true, isRequired: false, transformFunction: null }, termType: { classPropertyName: "termType", publicName: "termType", isSignal: true, isRequired: false, transformFunction: null }, termId: { classPropertyName: "termId", publicName: "termId", isSignal: true, isRequired: false, transformFunction: null }, jlogParentKey: { classPropertyName: "jlogParentKey", publicName: "jlogParentKey", isSignal: true, isRequired: false, transformFunction: null }, jlogParentIndex: { classPropertyName: "jlogParentIndex", publicName: "jlogParentIndex", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"is-flex is-gap-8 is-justify-content-space-between is-align-items-center is-my-2\">\n <div>\n <ng-content />\n </div>\n</div>\n\n<he-data-table class=\"is-mt-2 is-mb-1 is-bordered\" [small]=\"true\" maxHeight=\"320\">\n <table class=\"table is-fullwidth is-narrow is-striped\">\n <thead>\n <tr>\n <th class=\"width-auto has-border-right\">\n @if (enableFilterByTerm()) {\n <div class=\"field is-pb-1\">\n <div class=\"control is-expanded has-icons-right\">\n <input\n class=\"input search-input is-small\"\n [ngModel]=\"term()\"\n name=\"term\"\n placeholder=\"Select entry by name\"\n [ngbTypeahead]=\"suggestTerm\"\n [resultFormatter]=\"termFormatter\"\n [inputFormatter]=\"termFormatter\"\n [focusFirst]=\"true\"\n (focus)=\"typeaheadFocus($event)\"\n (selectItem)=\"term.set($event.item)\"\n container=\"body\"\n popupClass=\"is-small\" />\n <a class=\"icon is-small is-right\" [class.is-hidden]=\"!term()\" (click)=\"term.set(undefined)\">\n <he-svg-icon name=\"xmark\" />\n </a>\n </div>\n </div>\n }\n </th>\n <th class=\"has-border-right\"><span>Units</span></th>\n <th class=\"has-border-right\"><span>Aggregated</span></th>\n <th class=\"has-border-right\">\n <span title=\"The number of Cycles the value was aggregated from\">Observations</span>\n </th>\n <th class=\"has-border-right\"><span>Model</span></th>\n </tr>\n </thead>\n <tbody>\n @if (groups().length === 0) {\n <tr>\n <td class=\"has-border-right has-text-centered\" colspan=\"100\">\n <p class=\"is-p-1\">\n No aggregated data to show\n @if (term()) {\n <span>matching your search criteria</span>\n }\n <span>.</span>\n </p>\n </td>\n </tr>\n }\n @for (group of groups(); track trackByGroup($index, group)) {\n @let single = group.rows.length === 1;\n <tr [class.has-sub-rows]=\"group.canOpen\" [class.is-open]=\"group.isOpen\">\n <td class=\"width-auto has-border-right is-nowrap\" [attr.title]=\"group.term?.name\">\n <div class=\"is-flex is-align-items-flex-start is-gap-4\">\n @if (group.canOpen) {\n <a class=\"open-node\" (click)=\"toggleGroup(group)\">\n <he-svg-icon [name]=\"group.isOpen ? 'chevron-down' : 'chevron-right'\" />\n </a>\n }\n <he-node-link class=\"is-inline-block is-pre-wrap is-pr-2\" [node]=\"group.term\">\n <span class=\"break-word\" [innerHtml]=\"group.term?.name | compound: group.term?.termType\"></span>\n </he-node-link>\n </div>\n </td>\n\n @if (single) {\n <ng-container *ngTemplateOutlet=\"valueCells; context: { row: group.rows[0], term: group.term }\" />\n <ng-container *ngTemplateOutlet=\"modelCell; context: { row: group.rows[0] }\" />\n } @else {\n <td class=\"has-border-right\">\n <span class=\"is-nowrap\" [innerHtml]=\"group.term?.units | compound\"></span>\n </td>\n <td class=\"has-border-right is-nowrap\">\n @if (group.valueFormula) {\n <span\n class=\"has-formula\"\n [ngbPopover]=\"group.valueFormula\"\n popoverClass=\"is-narrow\"\n triggers=\"click\"\n container=\"body\">\n {{ group.value | precision: 3 | default: '-' }}\n </span>\n } @else {\n {{ group.value | precision: 3 | default: '-' }}\n }\n </td>\n <td class=\"has-border-right is-nowrap\">{{ group.observations | default: '-' }}</td>\n <ng-container *ngTemplateOutlet=\"modelCell\" />\n }\n </tr>\n\n @if (!single && group.isOpen) {\n @for (row of group.rows; track trackByRow($index, row)) {\n <tr class=\"is-sub-row\">\n <td class=\"width-auto has-border-right\">\n <div class=\"is-flex is-align-items-flex-start is-gap-4 is-pl-3\">\n <he-svg-icon class=\"sub-sub-row-icon\" name=\"chevron-double-right\" />\n <he-blank-node-identity\n [segments]=\"row.segments\"\n [scalars]=\"row.scalars\"\n [type]=\"group.type\"\n [fallback]=\"'entry ' + (row.index + 1)\" />\n </div>\n </td>\n <ng-container *ngTemplateOutlet=\"valueCells; context: { row, term: group.term }\" />\n <ng-container *ngTemplateOutlet=\"modelCell; context: { row }\" />\n </tr>\n }\n }\n }\n </tbody>\n </table>\n</he-data-table>\n\n<ng-template #valueCells let-row=\"row\" let-term=\"term\">\n <td class=\"has-border-right\">\n <span class=\"is-nowrap\" [innerHtml]=\"term?.units | compound\"></span>\n </td>\n <td class=\"has-border-right is-nowrap\">\n {{ row.displayValue | precision: 3 | default: '-' }}\n </td>\n <td class=\"has-border-right is-nowrap\">\n {{ row.observations | default: '-' }}\n </td>\n</ng-template>\n\n<!-- `row` is left out on a term group: the rules are the same for every entry it holds, so the guide\n is shown there too, but the values to substitute belong to one entry - those stay on the sub-rows -->\n<ng-template #modelCell let-row=\"row\">\n <td class=\"has-border-right\">\n <div class=\"is-flex is-align-self-stretch is-align-items-center is-gap-8\">\n <span class=\"is-flex-grow-1 is-nowrap\">{{ modelName }}</span>\n\n <div class=\"is-flex is-gap-4 is-flex-shrink-0 is-align-items-center\">\n <!-- nothing opens the panel when no rule applies: it would open on an empty popover -->\n @if (hasRules()) {\n @if (row) {\n <span\n class=\"is-nowrap is-clickable\"\n [ngbPopover]=\"aggregationRules\"\n autoClose=\"outside\"\n popoverClass=\"is-narrow\"\n triggers=\"manual\"\n #p=\"ngbPopover\"\n placement=\"bottom left right auto\"\n container=\"body\"\n (click)=\"p.isOpen() ? p.close() : p.open({ values: row.values, term: row.term })\">\n <span class=\"has-text-link\">Logs</span>\n </span>\n } @else {\n <span class=\"has-text-grey is-nowrap\">Expand for logs</span>\n }\n\n <div class=\"vertical-divider\"></div>\n }\n\n @if (guideEnabled) {\n <he-guide-overlay [pageId]=\"guidePage()\" [width]=\"500\" />\n } @else {\n <a [href]=\"guideHref()\" target=\"_blank\" rel=\"noopener\" (click)=\"$event.stopPropagation()\">\n <span>Docs</span>\n <he-svg-icon name=\"external-link\" class=\"ml-2\" />\n </a>\n }\n </div>\n </div>\n </td>\n</ng-template>\n\n<ng-template #aggregationRules let-values=\"values\" let-term=\"term\">\n <he-node-aggregated-formulas\n [termType]=\"termType()\"\n [termId]=\"termId()\"\n [nodeKey]=\"nodeKey()\"\n [term]=\"term\"\n [values]=\"values\"\n [worldAggregation]=\"worldAggregation()\"\n [subAggregation]=\"subAggregation()\" />\n</ng-template>\n", styles: [":host{display:block}:host .vertical-divider{width:1px;height:20px;background:#dbe3ea}:host .has-formula{cursor:help;border-bottom:1px dotted currentColor}::ng-deep .table{background-color:transparent}::ng-deep .table td.has-border-right{box-shadow:1px 0 #4c7194}::ng-deep .table td>div{min-height:24px}::ng-deep .table .has-sub-rows.is-open>td:first-child:before,::ng-deep .table .is-sub-row>td:first-child:before{display:block;position:absolute;content:\" \";background-color:#4c719433;height:100%;width:1px;top:0;left:14px}::ng-deep .table .has-sub-rows.is-open>td:first-child:before{top:25px}::ng-deep .table .is-sub-row .open-node>he-svg-icon,::ng-deep .table .is-sub-row .sub-sub-row-icon{height:16px!important;width:16px!important}::ng-deep .table .is-sub-sub-row td:first-child{padding-left:24px}::ng-deep .table th:last-child,::ng-deep .table td:last-child{min-width:12rem}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: NgbPopover, selector: "[ngbPopover]", inputs: ["animation", "autoClose", "ngbPopover", "popoverTitle", "placement", "popperOptions", "triggers", "positionTarget", "container", "disablePopover", "popoverClass", "popoverContext", "openDelay", "closeDelay"], outputs: ["shown", "hidden"], exportAs: ["ngbPopover"] }, { kind: "directive", type: NgbTypeahead, selector: "input[ngbTypeahead]", inputs: ["autocomplete", "container", "editable", "focusFirst", "inputFormatter", "ngbTypeahead", "resultFormatter", "resultTemplate", "selectOnExact", "showHint", "placement", "popperOptions", "popupClass"], outputs: ["selectItem"], exportAs: ["ngbTypeahead"] }, { kind: "component", type: DataTableComponent, selector: "he-data-table", inputs: ["minHeight", "maxHeight", "small"] }, { kind: "component", type: HESvgIconComponent, selector: "he-svg-icon", inputs: ["name", "size", "animation"] }, { kind: "component", type: NodeLinkComponent, selector: "he-node-link", inputs: ["node", "dataState", "showExternalLink", "linkClass"] }, { kind: "component", type: BlankNodeIdentityComponent, selector: "he-blank-node-identity", inputs: ["segments", "scalars", "type", "fallback"] }, { kind: "component", type: GuideOverlayComponent, selector: "he-guide-overlay", inputs: ["pageId", "width", "height", "positions"], outputs: ["widthChange", "heightChange"] }, { kind: "component", type: NodeAggregatedFormulasComponent, selector: "he-node-aggregated-formulas", inputs: ["termType", "termId", "nodeKey", "term", "values", "worldAggregation", "subAggregation", "substituted"], outputs: ["substitutedChange"] }, { kind: "pipe", type: CompoundPipe, name: "compound" }, { kind: "pipe", type: DefaultPipe, name: "default" }, { kind: "pipe", type: PrecisionPipe, name: "precision" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
12567
12728
|
}
|
|
12568
12729
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NodeAggregationLogsComponent, decorators: [{
|
|
12569
12730
|
type: Component$1,
|
|
12570
12731
|
args: [{ selector: 'he-node-aggregation-logs', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
12571
12732
|
NgTemplateOutlet,
|
|
12733
|
+
FormsModule,
|
|
12572
12734
|
NgbPopover,
|
|
12735
|
+
NgbTypeahead,
|
|
12573
12736
|
CompoundPipe,
|
|
12574
12737
|
DefaultPipe,
|
|
12575
12738
|
PrecisionPipe,
|
|
@@ -12579,7 +12742,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
|
|
|
12579
12742
|
BlankNodeIdentityComponent,
|
|
12580
12743
|
GuideOverlayComponent,
|
|
12581
12744
|
NodeAggregatedFormulasComponent
|
|
12582
|
-
], template: "<div class=\"is-flex is-gap-8 is-justify-content-space-between is-align-items-center is-my-2\">\n <div>\n <ng-content />\n </div>\n</div>\n\n<he-data-table class=\"is-mt-2 is-mb-1 is-bordered\" [small]=\"true\" maxHeight=\"320\">\n <table class=\"table is-fullwidth is-narrow is-striped\">\n <thead>\n <tr>\n <th class=\"width-auto has-border-right\"
|
|
12745
|
+
], template: "<div class=\"is-flex is-gap-8 is-justify-content-space-between is-align-items-center is-my-2\">\n <div>\n <ng-content />\n </div>\n</div>\n\n<he-data-table class=\"is-mt-2 is-mb-1 is-bordered\" [small]=\"true\" maxHeight=\"320\">\n <table class=\"table is-fullwidth is-narrow is-striped\">\n <thead>\n <tr>\n <th class=\"width-auto has-border-right\">\n @if (enableFilterByTerm()) {\n <div class=\"field is-pb-1\">\n <div class=\"control is-expanded has-icons-right\">\n <input\n class=\"input search-input is-small\"\n [ngModel]=\"term()\"\n name=\"term\"\n placeholder=\"Select entry by name\"\n [ngbTypeahead]=\"suggestTerm\"\n [resultFormatter]=\"termFormatter\"\n [inputFormatter]=\"termFormatter\"\n [focusFirst]=\"true\"\n (focus)=\"typeaheadFocus($event)\"\n (selectItem)=\"term.set($event.item)\"\n container=\"body\"\n popupClass=\"is-small\" />\n <a class=\"icon is-small is-right\" [class.is-hidden]=\"!term()\" (click)=\"term.set(undefined)\">\n <he-svg-icon name=\"xmark\" />\n </a>\n </div>\n </div>\n }\n </th>\n <th class=\"has-border-right\"><span>Units</span></th>\n <th class=\"has-border-right\"><span>Aggregated</span></th>\n <th class=\"has-border-right\">\n <span title=\"The number of Cycles the value was aggregated from\">Observations</span>\n </th>\n <th class=\"has-border-right\"><span>Model</span></th>\n </tr>\n </thead>\n <tbody>\n @if (groups().length === 0) {\n <tr>\n <td class=\"has-border-right has-text-centered\" colspan=\"100\">\n <p class=\"is-p-1\">\n No aggregated data to show\n @if (term()) {\n <span>matching your search criteria</span>\n }\n <span>.</span>\n </p>\n </td>\n </tr>\n }\n @for (group of groups(); track trackByGroup($index, group)) {\n @let single = group.rows.length === 1;\n <tr [class.has-sub-rows]=\"group.canOpen\" [class.is-open]=\"group.isOpen\">\n <td class=\"width-auto has-border-right is-nowrap\" [attr.title]=\"group.term?.name\">\n <div class=\"is-flex is-align-items-flex-start is-gap-4\">\n @if (group.canOpen) {\n <a class=\"open-node\" (click)=\"toggleGroup(group)\">\n <he-svg-icon [name]=\"group.isOpen ? 'chevron-down' : 'chevron-right'\" />\n </a>\n }\n <he-node-link class=\"is-inline-block is-pre-wrap is-pr-2\" [node]=\"group.term\">\n <span class=\"break-word\" [innerHtml]=\"group.term?.name | compound: group.term?.termType\"></span>\n </he-node-link>\n </div>\n </td>\n\n @if (single) {\n <ng-container *ngTemplateOutlet=\"valueCells; context: { row: group.rows[0], term: group.term }\" />\n <ng-container *ngTemplateOutlet=\"modelCell; context: { row: group.rows[0] }\" />\n } @else {\n <td class=\"has-border-right\">\n <span class=\"is-nowrap\" [innerHtml]=\"group.term?.units | compound\"></span>\n </td>\n <td class=\"has-border-right is-nowrap\">\n @if (group.valueFormula) {\n <span\n class=\"has-formula\"\n [ngbPopover]=\"group.valueFormula\"\n popoverClass=\"is-narrow\"\n triggers=\"click\"\n container=\"body\">\n {{ group.value | precision: 3 | default: '-' }}\n </span>\n } @else {\n {{ group.value | precision: 3 | default: '-' }}\n }\n </td>\n <td class=\"has-border-right is-nowrap\">{{ group.observations | default: '-' }}</td>\n <ng-container *ngTemplateOutlet=\"modelCell\" />\n }\n </tr>\n\n @if (!single && group.isOpen) {\n @for (row of group.rows; track trackByRow($index, row)) {\n <tr class=\"is-sub-row\">\n <td class=\"width-auto has-border-right\">\n <div class=\"is-flex is-align-items-flex-start is-gap-4 is-pl-3\">\n <he-svg-icon class=\"sub-sub-row-icon\" name=\"chevron-double-right\" />\n <he-blank-node-identity\n [segments]=\"row.segments\"\n [scalars]=\"row.scalars\"\n [type]=\"group.type\"\n [fallback]=\"'entry ' + (row.index + 1)\" />\n </div>\n </td>\n <ng-container *ngTemplateOutlet=\"valueCells; context: { row, term: group.term }\" />\n <ng-container *ngTemplateOutlet=\"modelCell; context: { row }\" />\n </tr>\n }\n }\n }\n </tbody>\n </table>\n</he-data-table>\n\n<ng-template #valueCells let-row=\"row\" let-term=\"term\">\n <td class=\"has-border-right\">\n <span class=\"is-nowrap\" [innerHtml]=\"term?.units | compound\"></span>\n </td>\n <td class=\"has-border-right is-nowrap\">\n {{ row.displayValue | precision: 3 | default: '-' }}\n </td>\n <td class=\"has-border-right is-nowrap\">\n {{ row.observations | default: '-' }}\n </td>\n</ng-template>\n\n<!-- `row` is left out on a term group: the rules are the same for every entry it holds, so the guide\n is shown there too, but the values to substitute belong to one entry - those stay on the sub-rows -->\n<ng-template #modelCell let-row=\"row\">\n <td class=\"has-border-right\">\n <div class=\"is-flex is-align-self-stretch is-align-items-center is-gap-8\">\n <span class=\"is-flex-grow-1 is-nowrap\">{{ modelName }}</span>\n\n <div class=\"is-flex is-gap-4 is-flex-shrink-0 is-align-items-center\">\n <!-- nothing opens the panel when no rule applies: it would open on an empty popover -->\n @if (hasRules()) {\n @if (row) {\n <span\n class=\"is-nowrap is-clickable\"\n [ngbPopover]=\"aggregationRules\"\n autoClose=\"outside\"\n popoverClass=\"is-narrow\"\n triggers=\"manual\"\n #p=\"ngbPopover\"\n placement=\"bottom left right auto\"\n container=\"body\"\n (click)=\"p.isOpen() ? p.close() : p.open({ values: row.values, term: row.term })\">\n <span class=\"has-text-link\">Logs</span>\n </span>\n } @else {\n <span class=\"has-text-grey is-nowrap\">Expand for logs</span>\n }\n\n <div class=\"vertical-divider\"></div>\n }\n\n @if (guideEnabled) {\n <he-guide-overlay [pageId]=\"guidePage()\" [width]=\"500\" />\n } @else {\n <a [href]=\"guideHref()\" target=\"_blank\" rel=\"noopener\" (click)=\"$event.stopPropagation()\">\n <span>Docs</span>\n <he-svg-icon name=\"external-link\" class=\"ml-2\" />\n </a>\n }\n </div>\n </div>\n </td>\n</ng-template>\n\n<ng-template #aggregationRules let-values=\"values\" let-term=\"term\">\n <he-node-aggregated-formulas\n [termType]=\"termType()\"\n [termId]=\"termId()\"\n [nodeKey]=\"nodeKey()\"\n [term]=\"term\"\n [values]=\"values\"\n [worldAggregation]=\"worldAggregation()\"\n [subAggregation]=\"subAggregation()\" />\n</ng-template>\n", styles: [":host{display:block}:host .vertical-divider{width:1px;height:20px;background:#dbe3ea}:host .has-formula{cursor:help;border-bottom:1px dotted currentColor}::ng-deep .table{background-color:transparent}::ng-deep .table td.has-border-right{box-shadow:1px 0 #4c7194}::ng-deep .table td>div{min-height:24px}::ng-deep .table .has-sub-rows.is-open>td:first-child:before,::ng-deep .table .is-sub-row>td:first-child:before{display:block;position:absolute;content:\" \";background-color:#4c719433;height:100%;width:1px;top:0;left:14px}::ng-deep .table .has-sub-rows.is-open>td:first-child:before{top:25px}::ng-deep .table .is-sub-row .open-node>he-svg-icon,::ng-deep .table .is-sub-row .sub-sub-row-icon{height:16px!important;width:16px!important}::ng-deep .table .is-sub-sub-row td:first-child{padding-left:24px}::ng-deep .table th:last-child,::ng-deep .table td:last-child{min-width:12rem}\n"] }]
|
|
12583
12746
|
}], propDecorators: { node: [{ type: i0.Input, args: [{ isSignal: true, alias: "node", required: false }] }], nodeKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "nodeKey", required: false }] }], termType: [{ type: i0.Input, args: [{ isSignal: true, alias: "termType", required: false }] }], termId: [{ type: i0.Input, args: [{ isSignal: true, alias: "termId", required: false }] }], jlogParentKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "jlogParentKey", required: false }] }], jlogParentIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "jlogParentIndex", required: false }] }] } });
|
|
12584
12747
|
|
|
12585
12748
|
const isValidDate = (date) => (date || '').trim().length === 10;
|
|
@@ -12978,13 +13141,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
|
|
|
12978
13141
|
], template: "@if (isGroupNode()) {\n <div class=\"tabs is-mb-1 | group-nodes-tabs\">\n <ul>\n @for (value of groupNodeValues(); track value) {\n <li\n [class.is-active]=\"selectedGroup() === value.value\"\n [ngbTooltip]=\"value.term.name\"\n placement=\"top\"\n container=\"body\">\n <a (click)=\"selectedGroup.set(value.value)\">\n <span class=\"is-capitalized is-pr-1\">{{ nodeKeyGroup() | pluralize: 1 }}:</span>\n <span>{{ value.value }}</span>\n </a>\n </li>\n }\n </ul>\n </div>\n}\n\n@if (isNodeKeyAllowed()) {\n @switch (selectedView()) {\n @case (View.table) {\n <ng-container *ngTemplateOutlet=\"selectView\" />\n\n @if (hasData()) {\n @if (hasVisibleData() || !hideIdentical()) {\n <he-data-table class=\"is-mt-3 is-bordered\" [small]=\"true\" maxHeight=\"320\">\n <table class=\"table is-fullwidth is-narrow is-striped\">\n <thead>\n @if (dataKeys().length > 1) {\n <tr class=\"has-text-weight-bold\">\n <th class=\"width-auto has-border-right\"></th>\n <th class=\"has-border-right\" [class.is-hidden]=\"isGroupNode()\"></th>\n @for (dataKey of dataKeys(); track dataKey; let dataKeyLast = $last) {\n @let blankNodes = data()[dataKey];\n @let blankNodesCount = countGroupVisibleNodes(blankNodes);\n @if (blankNodesCount > 0) {\n <th [attr.colspan]=\"blankNodesCount\" [class.has-border-right]=\"!dataKeyLast\">\n <span>{{ dataKey | keyToLabel }}</span>\n </th>\n }\n }\n </tr>\n }\n <tr class=\"has-text-weight-semibold\">\n <th class=\"width-auto has-border-right\"></th>\n <th class=\"has-border-right\" [class.is-hidden]=\"isGroupNode()\"></th>\n @for (dataKey of dataKeys(); track dataKey; let dataKeyLast = $last) {\n @let blankNodes = data()[dataKey];\n @for (node of blankNodes; track node.value.term.name; let nodeLast = $last) {\n @if (node.value.visible) {\n <th\n [attr.title]=\"node.value.term.name\"\n [class.has-border-right]=\"dataKeys().length > 1 && !dataKeyLast && nodeLast\">\n <he-node-link [node]=\"node.value.term\">\n <span\n [innerHtml]=\"\n node.value.term.name | ellipsis: 30 | compound: node.value.term.termType\n \"></span>\n </he-node-link>\n </th>\n }\n }\n }\n </tr>\n <tr class=\"is-italic has-text-weight-semibold\">\n <th class=\"width-auto has-border-right\"></th>\n <th class=\"has-border-right\" [class.is-hidden]=\"isGroupNode()\">\n <a [href]=\"schemaBaseUrl + '/Cycle#functionalUnit'\" target=\"_blank\">Functional unit</a>\n </th>\n @for (dataKey of dataKeys(); track dataKey; let dataKeyLast = $last) {\n @let blankNodes = data()[dataKey];\n @for (node of blankNodes; track node.value.term.name; let nodeLast = $last) {\n @if (node.value.visible) {\n <th\n [attr.title]=\"node.value.term.units\"\n [class.has-border-right]=\"dataKeys().length > 1 && !dataKeyLast && nodeLast\">\n <span [innerHtml]=\"node.value.term.units | compound\"></span>\n <he-terms-units-description class=\"is-inline-block is-ml-2\" [term]=\"node.value.term\" />\n </th>\n }\n }\n }\n </tr>\n </thead>\n <tbody>\n @for (cycle of cycles(); track nodeVersionKey(cycle); let cycleIndex = $index) {\n <tr [class.is-suggested]=\"$any(cycle).suggested\">\n <td class=\"width-auto has-border-right\" [attr.title]=\"defaultLabel(cycle)\">\n <he-node-link [node]=\"cycleNode(cycle)\">\n <span class=\"has-text-ellipsis is-ellipsis-3\">\n @if ($any(cycle).suggested) {\n <he-svg-icon name=\"compare\" />\n } @else {\n <span>{{ cycleIndex + 1 }}.</span>\n }\n <span class=\"is-pl-1\">{{ defaultLabel(cycle) }}</span>\n </span>\n </he-node-link>\n </td>\n <td class=\"has-border-right\" [class.is-hidden]=\"isGroupNode()\">\n <he-cycles-functional-unit-measure [cycle]=\"cycle\" />\n </td>\n @for (dataKey of dataKeys(); track dataKey; let dataKeyLast = $last) {\n @let blankNodes = data()[dataKey];\n @for (node of blankNodes; track node.value.term.name; let nodeLast = $last) {\n @if (node.value.visible) {\n @let cycleData = node.value.values[nodeVersionKey(cycle)];\n <td\n class=\"is-nowrap\"\n [class.has-border-right]=\"dataKeys().length > 1 && !dataKeyLast && nodeLast\">\n @if (cycleData) {\n <span\n class=\"trigger-popover\"\n [ngbPopover]=\"details\"\n autoClose=\"outside\"\n popoverClass=\"is-narrow is-overflow-visible\"\n placement=\"left bottom auto\"\n container=\"body\"\n [popoverContext]=\"{ data: cycleData, cycle, key: dataKey }\">\n <span pointer>\n {{ cycleData.propertyValue | precision: 3 | default: '-' }}\n </span>\n <he-blank-node-state\n class=\"ml-1\"\n [dataState]=\"dataState()\"\n [node]=\"cycleData.node\"\n key=\"value\" />\n </span>\n } @else {\n <span>-</span>\n }\n </td>\n }\n }\n }\n </tr>\n }\n </tbody>\n </table>\n </he-data-table>\n } @else {\n <div class=\"is-pt-3 has-text-centered\">\n <span>No differences between the nodes compared.</span>\n </div>\n }\n <div class=\"is-flex is-align-items-center is-flex-wrap-wrap is-justify-content-space-between is-mt-2\">\n <he-blank-node-state-notice\n [dataState]=\"dataState()\"\n [showDeleted]=\"firstNodeKey() === BlankNodesKey.emissions\" />\n <div class=\"is-flex is-flex-wrap-wrap is-gap-8\">\n @if (showHideZeroValues()) {\n <div class=\"field is-relative is-mb-0\">\n <input\n type=\"checkbox\"\n class=\"switch is-small is-rounded\"\n [id]=\"componentId() + 'hideZeroValues'\"\n name=\"hideZeroValues\"\n [(ngModel)]=\"hideZeroValues\" />\n <label [for]=\"componentId() + 'hideZeroValues'\">\n <span>\n Hide\n <b>0</b>\n values\n </span>\n </label>\n </div>\n }\n @if (cycles().length > 1) {\n <div class=\"field is-relative is-mb-0\">\n <input\n type=\"checkbox\"\n class=\"switch is-small is-rounded\"\n [id]=\"componentId() + 'hideIdenticalValues'\"\n name=\"hideIdenticalValues\"\n [(ngModel)]=\"hideIdenticalSelected\" />\n <label [for]=\"componentId() + 'hideIdenticalValues'\">\n <span>Hide identical values</span>\n </label>\n </div>\n }\n </div>\n </div>\n } @else {\n <div class=\"is-pt-3 has-text-centered\">\n <span>No data available</span>\n @if (filterTerm()) {\n <span class=\"is-pl-1\">matching your search criteria</span>\n }\n <span>.</span>\n @if (showSwitchToRecalculated()) {\n <span>\n Switch to\n <code>recalculated</code>\n version.\n </span>\n }\n </div>\n }\n }\n @case (View.chart) {\n @switch (firstNodeKey()) {\n @case (BlankNodesKey.emissions) {\n <he-cycles-emissions-chart [cycles]=\"cycles()\">\n <ng-container *ngTemplateOutlet=\"selectView\" />\n </he-cycles-emissions-chart>\n }\n }\n }\n @case (View.aggregationLogs) {\n <ng-container *ngTemplateOutlet=\"selectView\" />\n\n @if (selectedNode()) {\n <he-node-aggregation-logs\n [node]=\"selectedNode()\"\n [nodeKey]=\"selectedNodeKey()\"\n [termType]=\"primaryProductTermType()\"\n [termId]=\"primaryProductTermId()\"\n [jlogParentKey]=\"nodeKeyGroup()\"\n [jlogParentIndex]=\"jlogParentIndex()\">\n @if (nodeKeys().length > 1) {\n <div class=\"tabs is-m-0\">\n <ul>\n @for (nodeKey of nodeKeys(); track nodeKey) {\n <li [class.is-active]=\"selectedNodeKey() === nodeKey\">\n <a (click)=\"selectedNodeKey.set(nodeKey)\">{{ nodeKey | keyToLabel }}</a>\n </li>\n }\n </ul>\n </div>\n }\n </he-node-aggregation-logs>\n }\n }\n @case (View.timeline) {\n <he-cycles-nodes-timeline\n [values]=\"timelineValues()\"\n [minDate]=\"selectedCycle().startDate\"\n [maxDate]=\"selectedCycle().endDate\">\n <ng-container *ngTemplateOutlet=\"selectView\" />\n </he-cycles-nodes-timeline>\n }\n @case (View.logs) {\n <!-- keep the cycle selector visible even when the selected cycle has no grouped node (e.g. a cycle\n with no transformations under \"Transformation: Inputs\"), so the user can switch to one that has -->\n <ng-container *ngTemplateOutlet=\"selectView\" />\n\n @if (selectedNode()) {\n <he-node-logs-models\n [node]=\"selectedNode()\"\n [cycle]=\"selectedNode()\"\n [nodeKey]=\"selectedNodeKey()\"\n [logsKey]=\"selectedLogsKey()\"\n [jlogParentKey]=\"nodeKeyGroup()\"\n [jlogParentIndex]=\"jlogParentIndex()\"\n [originalValues]=\"selectedOriginalValues()\"\n [recalculatedValues]=\"selectedRecalculatedValues()\"\n [filterTermTypes]=\"filterTermTypes()\">\n @if (nodeKeys().length > 1) {\n <div class=\"tabs is-m-0\">\n <ul>\n @for (nodeKey of nodeKeys(); track nodeKey) {\n <li [class.is-active]=\"selectedNodeKey() === nodeKey\">\n <a (click)=\"selectedNodeKey.set(nodeKey)\">{{ nodeKey | keyToLabel }}</a>\n </li>\n }\n </ul>\n </div>\n }\n </he-node-logs-models>\n } @else if (isGroupNode()) {\n <p class=\"is-p-3 has-text-grey\">\n No recalculation logs for the selected {{ nodeKeyGroup() | pluralize: 1 }} in this cycle \u2014 select another\n cycle above.\n </p>\n }\n }\n }\n}\n\n<ng-template #selectView>\n <div class=\"is-flex is-gap-8 is-align-items-center is-justify-content-space-between\">\n <div class=\"is-flex is-gap-8 is-align-items-center\">\n @if (selectedView() === View.table) {\n @if (hasData()) {\n <button class=\"button is-small is-ghost is-p-2\" (click)=\"showDownload()\">\n <he-svg-icon name=\"download\" />\n </button>\n }\n <he-search-extend\n class=\"is-secondary\"\n collapsedClass=\"is-p-2\"\n placeholder=\"Filter terms by name\"\n (searchText)=\"filterTerm.set($event)\" />\n } @else if (showSelectCycle()) {\n <ng-container *ngTemplateOutlet=\"selectCycle\" />\n }\n </div>\n\n @if (views()?.length > 1) {\n <div class=\"field has-addons button-segments\">\n @for (view of views(); track view) {\n <div class=\"control\">\n <button\n class=\"button is-small\"\n [class.is-selected]=\"selectedView() === view\"\n (click)=\"selectedView.set(view)\">\n <he-svg-icon\n name=\"checkmark\"\n aria-hidden=\"true\"\n class=\"is-hidden-mobile\"\n [class.is-hidden-tablet]=\"selectedView() !== view\" />\n <he-svg-icon\n [name]=\"viewIcon[view]\"\n aria-hidden=\"true\"\n [class.is-hidden-tablet]=\"selectedView() === view\" />\n <span class=\"is-hidden-mobile\">{{ view }}</span>\n </button>\n </div>\n }\n </div>\n }\n </div>\n</ng-template>\n\n<ng-template #selectCycle>\n @if (selectableCycles().length > 1) {\n <div class=\"field is-horizontal is-mb-0\">\n <div class=\"field-label is-normal\">\n <label class=\"label has-text-secondary is-nowrap\" for=\"selectCycle\">Cycle</label>\n </div>\n <div class=\"field-body\">\n <div class=\"field\">\n <div class=\"control is-expanded\">\n <div class=\"select is-small is-fullwidth\">\n <select [value]=\"selectedIndex()\" (change)=\"selectIndex($event)\" if=\"selectCycle\">\n @for (entry of selectableCycles(); track nodeVersionKey(entry.cycle)) {\n <option [value]=\"entry.index\">{{ entry.index + 1 }}. {{ defaultLabel(entry.cycle) }}</option>\n }\n </select>\n </div>\n </div>\n </div>\n </div>\n </div>\n }\n</ng-template>\n\n<ng-template #details let-node=\"cycle\" let-data=\"data\" let-key=\"key\">\n <p>\n <b>{{ defaultLabel(node) }}</b>\n </p>\n <he-node-value-details\n class=\"is-overflow-visible\"\n [data]=\"data\"\n [dataState]=\"dataState()\"\n [nodeType]=\"node['@type']\"\n [dataKey]=\"key\"\n [aggregated]=\"node.aggregated\" />\n</ng-template>\n", styles: [":host{display:block}he-data-table ::ng-deep .table thead tr th:nth-child(2),he-data-table ::ng-deep .table tbody tr td:nth-child(2){max-width:106px;width:106px}\n"] }]
|
|
12979
13142
|
}], ctorParameters: () => [], propDecorators: { dataState: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataState", required: false }] }], nodeKeys: [{ type: i0.Input, args: [{ isSignal: true, alias: "nodeKeys", required: true }] }], nodeKeyGroup: [{ type: i0.Input, args: [{ isSignal: true, alias: "nodeKeyGroup", required: false }] }], hideIdenticalValues: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideIdenticalValues", required: false }] }] } });
|
|
12980
13143
|
|
|
13144
|
+
const labelMaxLength = 25;
|
|
12981
13145
|
class CyclesResultComponent {
|
|
12982
13146
|
constructor() {
|
|
12983
13147
|
this.cycles = input.required(...(ngDevMode ? [{ debugName: "cycles" }] : []));
|
|
12984
13148
|
this.productsPerCycle = computed(() => groupNodesByTerm(this.cycles(), 'products'), ...(ngDevMode ? [{ debugName: "productsPerCycle" }] : []));
|
|
12985
|
-
this.chartLabels = computed(() => this.cycles()
|
|
12986
|
-
.map((cycle, index) => ({ cycle, index }))
|
|
12987
|
-
.map(({ cycle, index }) => `${index + 1}. ${defaultLabel(cycle)}`), ...(ngDevMode ? [{ debugName: "chartLabels" }] : []));
|
|
13149
|
+
this.chartLabels = computed(() => nodeChartLabels(this.cycles(), labelMaxLength), ...(ngDevMode ? [{ debugName: "chartLabels" }] : []));
|
|
12988
13150
|
this.chartDatasets = computed(() => Object.values(this.productsPerCycle() ?? {}).map(({ term: { name, units, '@id': termId }, values }, index) => {
|
|
12989
13151
|
const color = getColor(index);
|
|
12990
13152
|
return {
|
|
@@ -13032,7 +13194,7 @@ class CyclesResultComponent {
|
|
|
13032
13194
|
};
|
|
13033
13195
|
Chart.defaults.scales.category.ticks.callback = function (val) {
|
|
13034
13196
|
const label = this.getLabelForValue(val);
|
|
13035
|
-
return ellipsis(`${label}`,
|
|
13197
|
+
return ellipsis(`${label}`, labelMaxLength);
|
|
13036
13198
|
};
|
|
13037
13199
|
}
|
|
13038
13200
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: CyclesResultComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
@@ -15876,6 +16038,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
|
|
|
15876
16038
|
}]
|
|
15877
16039
|
}] });
|
|
15878
16040
|
|
|
16041
|
+
/**
|
|
16042
|
+
* The product of an impact assessment, which aggregated ones carry as a `term`.
|
|
16043
|
+
*/
|
|
16044
|
+
const impactAssessmentProduct = (impactAssessment) => impactAssessment?.product?.term || impactAssessment?.term;
|
|
16045
|
+
|
|
15879
16046
|
/* eslint-disable complexity */
|
|
15880
16047
|
var ChartNodeType;
|
|
15881
16048
|
(function (ChartNodeType) {
|
|
@@ -17089,7 +17256,7 @@ class ImpactAssessmentsIndicatorBreakdownChartComponent {
|
|
|
17089
17256
|
return [blankNodeTermId, modelId, impactTermId].join('-');
|
|
17090
17257
|
}
|
|
17091
17258
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ImpactAssessmentsIndicatorBreakdownChartComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
17092
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: ImpactAssessmentsIndicatorBreakdownChartComponent, isStandalone: true, selector: "he-impact-assessments-indicator-breakdown-chart", inputs: { impactAssessment: { classPropertyName: "impactAssessment", publicName: "impactAssessment", isSignal: true, isRequired: true, transformFunction: null }, indicators: { classPropertyName: "indicators", publicName: "indicators", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"is-flex is-gap-8 is-justify-content-space-between is-align-items-center is-mb-3\">\n <he-chart-export-button [chart]=\"chart\" [chartExportFn]=\"chartExportFn\" [exportFormats]=\"exportFormats\" />\n\n <ng-content />\n</div>\n\n@if (logsResource.isLoading()) {\n <div class=\"has-text-center py-3\">\n <he-svg-icon name=\"loading\" animation=\"spin\" size=\"40\" />\n </div>\n} @else if (terms()?.length) {\n <div class=\"is-flex is-align-items-center is-gap-12 is-mb-2 | breakdown-actions-table\">\n @if (terms()?.length) {\n <div class=\"control is-expanded is-flex-grow-1\">\n <div class=\"select is-fullwidth is-small\">\n <select [(ngModel)]=\"selectedTermId\" name=\"selectedTermId\">\n @for (term of terms(); track term['@id']) {\n <option [value]=\"term['@id']\">{{ term.name }}</option>\n }\n </select>\n </div>\n </div>\n }\n @if (methods()?.length) {\n <div class=\"control is-expanded is-flex-shrink-0\">\n <div class=\"select is-fullwidth is-small\">\n <select [(ngModel)]=\"selectedMethodId\" name=\"selectedMethodId\">\n @for (term of methods(); track term['@id']) {\n <option [value]=\"term['@id']\">{{ term.name }}</option>\n }\n </select>\n </div>\n </div>\n }\n <div class=\"control is-expanded is-flex-shrink-0\">\n <div class=\"select is-fullwidth is-small\">\n <select [(ngModel)]=\"selectedCategory\" name=\"selectedCategory\">\n <option [ngValue]=\"undefined\">No Disaggregation</option>\n @for (category of categories; track category.key) {\n <option [value]=\"category.key\">{{ category.label }}</option>\n }\n </select>\n </div>\n </div>\n\n <div class=\"is-flex is-justify-content-space-between\">\n <div class=\"field is-relative is-mb-0 is-hidden-tablet\">\n <input\n type=\"checkbox\"\n class=\"switch is-small is-rounded is-secondary\"\n id=\"displayValue\"\n name=\"displayValue\"\n [(ngModel)]=\"displayValue\" />\n <label for=\"displayValue\">Show numerical value</label>\n </div>\n </div>\n </div>\n}\n\n@if (!logsResource.isLoading() && noData()) {\n <div class=\"chart-area-border\">\n <p class=\"has-text-centered\">\n <span>No breakdown available for</span>\n @if (selectedTerm()) {\n <span class=\"is-pl-1\">{{ selectedTerm().name }}</span>\n }\n @if (selectedMethod()) {\n <span class=\"is-pl-1\">({{ selectedMethod().name }})</span>\n }\n <span>.</span>\n </p>\n </div>\n}\n\n<he-horizontal-bar-chart\n #chart=\"horizontalBarChart\"\n class=\"is-relative h-100\"\n [class.is-hidden]=\"!logsResource.isLoading() && noData()\"\n [title]=\"selectedTerm()?.units\"\n [config]=\"configuration()\"\n [data]=\"chartData()\"\n [max]=\"totalPositive()\"\n [maximumValues]=\"maximumValues()\"\n [showExportButton]=\"false\"\n [showNegativeValues]=\"true\"\n [tooltipFn]=\"chartTooltipFn\"\n [afterBarDrawSettings]=\"afterBarDrawSettings()\" />\n", styles: [":host{display:block;overflow:visible}@media screen and (max-width:767px){.chart-area-border{padding:0}}@media screen and (max-width:767px){.breakdown-actions-table{flex-direction:column;align-items:flex-start!important}}.breakdown-legend{background:#fafafa}.breakdown-legend--color{width:8px;height:8px;border-radius:50%}\n"], dependencies: [{ kind: "component", type: HESvgIconComponent, selector: "he-svg-icon", inputs: ["name", "size", "animation"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: HorizontalBarChartComponent, selector: "he-horizontal-bar-chart", inputs: ["tooltipFn", "afterBarDrawSettings", "minHeight", "maxHeight"], exportAs: ["horizontalBarChart"] }, { kind: "component", type: ChartExportButtonComponent, selector: "he-chart-export-button", inputs: ["buttonClass", "chart", "config", "exportFormats", "chartExportFn"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
17259
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: ImpactAssessmentsIndicatorBreakdownChartComponent, isStandalone: true, selector: "he-impact-assessments-indicator-breakdown-chart", inputs: { impactAssessment: { classPropertyName: "impactAssessment", publicName: "impactAssessment", isSignal: true, isRequired: true, transformFunction: null }, indicators: { classPropertyName: "indicators", publicName: "indicators", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"is-flex is-gap-8 is-justify-content-space-between is-align-items-center is-mb-3\">\n <he-chart-export-button [chart]=\"chart\" [chartExportFn]=\"chartExportFn\" [exportFormats]=\"exportFormats\" />\n\n <ng-content />\n</div>\n\n@if (logsResource.isLoading()) {\n <div class=\"has-text-center py-3\">\n <he-svg-icon name=\"loading\" animation=\"spin\" size=\"40\" />\n </div>\n} @else if (terms()?.length) {\n <div class=\"is-flex is-align-items-center is-gap-12 is-mb-2 | breakdown-actions-table\">\n @if (terms()?.length) {\n <div class=\"control is-expanded is-flex-grow-1\">\n <div class=\"select is-fullwidth is-small\">\n <select [(ngModel)]=\"selectedTermId\" name=\"selectedTermId\">\n @for (term of terms(); track term['@id']) {\n <option [value]=\"term['@id']\">{{ term.name }}</option>\n }\n </select>\n </div>\n </div>\n }\n @if (methods()?.length) {\n <div class=\"control is-expanded is-flex-shrink-0\">\n <div class=\"select is-fullwidth is-small\">\n <select [(ngModel)]=\"selectedMethodId\" name=\"selectedMethodId\">\n @for (term of methods(); track term['@id']) {\n <option [value]=\"term['@id']\">{{ term.name }}</option>\n }\n </select>\n </div>\n </div>\n }\n <div class=\"control is-expanded is-flex-shrink-0\">\n <div class=\"select is-fullwidth is-small\">\n <select [(ngModel)]=\"selectedCategory\" name=\"selectedCategory\">\n <option [ngValue]=\"undefined\">No Disaggregation</option>\n @for (category of categories; track category.key) {\n <option [value]=\"category.key\">{{ category.label }}</option>\n }\n </select>\n </div>\n </div>\n\n <div class=\"is-flex is-justify-content-space-between\">\n <div class=\"field is-relative is-mb-0 is-hidden-tablet\">\n <input\n type=\"checkbox\"\n class=\"switch is-small is-rounded is-secondary\"\n id=\"displayValue\"\n name=\"displayValue\"\n [(ngModel)]=\"displayValue\" />\n <label for=\"displayValue\">Show numerical value</label>\n </div>\n </div>\n </div>\n}\n\n@if (!logsResource.isLoading() && noData()) {\n <div class=\"chart-area-border\">\n <p class=\"has-text-centered\">\n <span>No breakdown available for</span>\n @if (selectedTerm()) {\n <span class=\"is-pl-1\">{{ selectedTerm().name }}</span>\n }\n @if (selectedMethod()) {\n <span class=\"is-pl-1\">({{ selectedMethod().name }})</span>\n }\n <span>.</span>\n </p>\n </div>\n}\n\n<he-horizontal-bar-chart\n #chart=\"horizontalBarChart\"\n class=\"is-relative h-100\"\n [class.is-hidden]=\"!logsResource.isLoading() && noData()\"\n [title]=\"selectedTerm()?.units\"\n [config]=\"configuration()\"\n [data]=\"chartData()\"\n [max]=\"totalPositive()\"\n [maximumValues]=\"maximumValues()\"\n [showExportButton]=\"false\"\n [showNegativeValues]=\"true\"\n [tooltipFn]=\"chartTooltipFn\"\n [afterBarDrawSettings]=\"afterBarDrawSettings()\" />\n", styles: [":host{display:block;overflow:visible}@media screen and (max-width:767px){.chart-area-border{padding:0}}@media screen and (max-width:767px){.breakdown-actions-table{flex-direction:column;align-items:flex-start!important}}.breakdown-legend{background:#fafafa}.breakdown-legend--color{width:8px;height:8px;border-radius:50%}\n"], dependencies: [{ kind: "component", type: HESvgIconComponent, selector: "he-svg-icon", inputs: ["name", "size", "animation"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: HorizontalBarChartComponent, selector: "he-horizontal-bar-chart", inputs: ["tooltipFn", "afterBarDrawSettings", "axisTooltipFn", "axisLabelClickFn", "minHeight", "maxHeight"], exportAs: ["horizontalBarChart"] }, { kind: "component", type: ChartExportButtonComponent, selector: "he-chart-export-button", inputs: ["buttonClass", "chart", "config", "exportFormats", "chartExportFn"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
17093
17260
|
}
|
|
17094
17261
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ImpactAssessmentsIndicatorBreakdownChartComponent, decorators: [{
|
|
17095
17262
|
type: Component$1,
|
|
@@ -17097,10 +17264,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
|
|
|
17097
17264
|
}], ctorParameters: () => [], propDecorators: { impactAssessment: [{ type: i0.Input, args: [{ isSignal: true, alias: "impactAssessment", required: true }] }], indicators: [{ type: i0.Input, args: [{ isSignal: true, alias: "indicators", required: false }] }] } });
|
|
17098
17265
|
|
|
17099
17266
|
const impactValue = (impact, values) => (values[nodeVersionKey(impact)]?.nodes[0] || { value: 0 }).value;
|
|
17100
|
-
const impactName = (impact, index) => `${index + 1}. ${defaultLabel(impact)}`;
|
|
17101
17267
|
const termAllowed$1 = (filterTermTypes = [], term) => !filterTermTypes?.length || (filterTermTypes || []).includes(term?.termType);
|
|
17102
17268
|
class ImpactAssessmentsIndicatorsChartComponent {
|
|
17103
17269
|
constructor() {
|
|
17270
|
+
this.route = inject(ActivatedRoute);
|
|
17104
17271
|
this.nodeStoreService = inject(HeNodeStoreService);
|
|
17105
17272
|
this.nodeService = inject(HeNodeService);
|
|
17106
17273
|
this.emissionCategoryService = inject(CyclesEmissionsCategoryService);
|
|
@@ -17111,9 +17278,19 @@ class ImpactAssessmentsIndicatorsChartComponent {
|
|
|
17111
17278
|
this.filterTermTypes = input([], ...(ngDevMode ? [{ debugName: "filterTermTypes" }] : []));
|
|
17112
17279
|
this.categories = this.emissionCategoryService.categories;
|
|
17113
17280
|
this.selectedCategory = signal(undefined, ...(ngDevMode ? [{ debugName: "selectedCategory" }] : []));
|
|
17114
|
-
this.
|
|
17281
|
+
this.dataVersion = toSignal(this.route.queryParams.pipe(map(({ dataVersion }) => dataVersion)));
|
|
17282
|
+
this.allImpactAssessments = computed(() => this.nodeStoreService.findByState(NodeType.ImpactAssessment, DataState.recalculated), ...(ngDevMode ? [{ debugName: "allImpactAssessments" }] : []));
|
|
17283
|
+
this.products = computed(() => uniqBy(this.allImpactAssessments().map(impactAssessmentProduct).filter(Boolean), '@id').sort((a, b) => a.name.localeCompare(b.name)), ...(ngDevMode ? [{ debugName: "products" }] : []));
|
|
17284
|
+
this.selectedProductId = signal(undefined, ...(ngDevMode ? [{ debugName: "selectedProductId" }] : []));
|
|
17285
|
+
// labels are built from every impact assessment, so a bar keeps the number it has in the table
|
|
17286
|
+
// view whichever product is selected
|
|
17287
|
+
this.labels = computed(() => nodeChartLabels(this.allImpactAssessments(), chartLabelMaxLength), ...(ngDevMode ? [{ debugName: "labels" }] : []));
|
|
17288
|
+
this.displayedImpactAssessments = computed(() => this.allImpactAssessments()
|
|
17289
|
+
.map((impactAssessment, index) => ({ impactAssessment, index, label: this.labels()[index] }))
|
|
17290
|
+
.filter(({ impactAssessment }) => !this.selectedProductId() || impactAssessmentProduct(impactAssessment)?.['@id'] === this.selectedProductId()), ...(ngDevMode ? [{ debugName: "displayedImpactAssessments" }] : []));
|
|
17291
|
+
this.impactAssessments = computed(() => this.displayedImpactAssessments().map(({ impactAssessment }) => impactAssessment), ...(ngDevMode ? [{ debugName: "impactAssessments" }] : []));
|
|
17115
17292
|
this.contributionsResource = rxResource({
|
|
17116
|
-
params: () => ({ impactAssessments: this.
|
|
17293
|
+
params: () => ({ impactAssessments: this.allImpactAssessments() }),
|
|
17117
17294
|
stream: ({ params: { impactAssessments } }) => from(impactAssessments).pipe(mergeMap(impactAssessment => this.nodeService.getContributions$(impactAssessment).pipe(map(contributions => ({
|
|
17118
17295
|
impactAssessment,
|
|
17119
17296
|
contributions: simplifyContributions(impactAssessment, contributions)
|
|
@@ -17123,7 +17300,7 @@ class ImpactAssessmentsIndicatorsChartComponent {
|
|
|
17123
17300
|
}, {}))
|
|
17124
17301
|
});
|
|
17125
17302
|
this.contributionsPerImpactAssessment = computed(() => this.contributionsResource.value() ?? {}, ...(ngDevMode ? [{ debugName: "contributionsPerImpactAssessment" }] : []));
|
|
17126
|
-
this.termsMap = computed(() => this.
|
|
17303
|
+
this.termsMap = computed(() => this.allImpactAssessments()
|
|
17127
17304
|
.flatMap(impact => [...impact.emissionsResourceUse, ...impact.impacts])
|
|
17128
17305
|
.reduce((prev, curr) => {
|
|
17129
17306
|
prev[curr.term['@id']] = curr.term;
|
|
@@ -17149,12 +17326,12 @@ class ImpactAssessmentsIndicatorsChartComponent {
|
|
|
17149
17326
|
this.methods = computed(() => unique(this.termToMethods()[this.selectedTerm()?.['@id']]), ...(ngDevMode ? [{ debugName: "methods" }] : []));
|
|
17150
17327
|
this.selectedMethod = computed(() => this.methods().find(term => term['@id'] == this.selectedMethodId()), ...(ngDevMode ? [{ debugName: "selectedMethod" }] : []));
|
|
17151
17328
|
this.groupedValues = computed(() => this.indicatorPerImpactAssessment()?.[this.selectedTerm()?.name]?.values || {}, ...(ngDevMode ? [{ debugName: "groupedValues" }] : []));
|
|
17152
|
-
this.selectedContributionData = computed(() => Object.fromEntries(
|
|
17153
|
-
|
|
17154
|
-
|
|
17329
|
+
this.selectedContributionData = computed(() => Object.fromEntries(this.impactAssessments().map(impact => [
|
|
17330
|
+
nodeVersionKey(impact),
|
|
17331
|
+
this.contributionsPerImpactAssessment()[nodeVersionKey(impact)]?.[this.selectedTermId()]?.[this.selectedMethodId()] || {}
|
|
17155
17332
|
])), ...(ngDevMode ? [{ debugName: "selectedContributionData" }] : []));
|
|
17156
17333
|
this.contributionTerms = computed(() => unique(Object.values(this.selectedContributionData()).flatMap(v => Object.keys(v))), ...(ngDevMode ? [{ debugName: "contributionTerms" }] : []));
|
|
17157
|
-
this.enableContributions = computed(() =>
|
|
17334
|
+
this.enableContributions = computed(() => this.impactAssessments().every(impact => !!this.contributionsPerImpactAssessment()[nodeVersionKey(impact)]), ...(ngDevMode ? [{ debugName: "enableContributions" }] : []));
|
|
17158
17335
|
this.contributionData = computed(() => this.contributionTerms().map((term, index) => ({
|
|
17159
17336
|
id: term,
|
|
17160
17337
|
label: this.termsMap()[term]?.name || term,
|
|
@@ -17165,12 +17342,14 @@ class ImpactAssessmentsIndicatorsChartComponent {
|
|
|
17165
17342
|
? this.contributionData()
|
|
17166
17343
|
.filter(({ values }) => !values.every(v => !v))
|
|
17167
17344
|
.sort((a, b) => Math.max(...b.values.map(v => Math.abs(v))) - Math.max(...a.values.map(v => Math.abs(v))))
|
|
17168
|
-
: this.
|
|
17169
|
-
label
|
|
17170
|
-
count: impactValue(
|
|
17171
|
-
color: listColor(
|
|
17345
|
+
: this.displayedImpactAssessments().map(({ impactAssessment, index, label }) => ({
|
|
17346
|
+
label,
|
|
17347
|
+
count: impactValue(impactAssessment, this.groupedValues()),
|
|
17348
|
+
color: listColor(impactAssessment, index)
|
|
17172
17349
|
})), ...(ngDevMode ? [{ debugName: "chartData" }] : []));
|
|
17173
|
-
this.chartLabels = computed(() => this.
|
|
17350
|
+
this.chartLabels = computed(() => this.displayedImpactAssessments().map(({ label }) => label), ...(ngDevMode ? [{ debugName: "chartLabels" }] : []));
|
|
17351
|
+
this.axisTooltipFn = (label, index) => this.impactLabelTooltip(index) || label;
|
|
17352
|
+
this.axisLabelClickFn = index => this.openImpactAssessment(index);
|
|
17174
17353
|
this.exportFormats = computed(() => [
|
|
17175
17354
|
...exportFormats,
|
|
17176
17355
|
this.enableContributions()
|
|
@@ -17211,12 +17390,22 @@ class ImpactAssessmentsIndicatorsChartComponent {
|
|
|
17211
17390
|
}
|
|
17212
17391
|
});
|
|
17213
17392
|
}
|
|
17393
|
+
impactLabelTooltip(index) {
|
|
17394
|
+
const impactAssessment = this.displayedImpactAssessments()[index]?.impactAssessment;
|
|
17395
|
+
return impactAssessment
|
|
17396
|
+
? [`${index + 1}. ${defaultLabel(impactAssessment)}`, impactAssessment['@id']].filter(Boolean).join('<br />')
|
|
17397
|
+
: '';
|
|
17398
|
+
}
|
|
17399
|
+
openImpactAssessment(index) {
|
|
17400
|
+
const impactAssessment = this.displayedImpactAssessments()[index]?.impactAssessment;
|
|
17401
|
+
return impactAssessment ? openNodeUrl(impactAssessment, this.dataVersion()) : undefined;
|
|
17402
|
+
}
|
|
17214
17403
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ImpactAssessmentsIndicatorsChartComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
17215
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: ImpactAssessmentsIndicatorsChartComponent, isStandalone: true, selector: "he-impact-assessments-indicators-chart", inputs: { key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: false, transformFunction: null }, filterTermTypes: { classPropertyName: "filterTermTypes", publicName: "filterTermTypes", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "barChart", first: true, predicate: HorizontalBarChartComponent, descendants: true, isSignal: true }, { propertyName: "contributionChart", first: true, predicate: ContributionChartComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"is-flex is-gap-8 is-justify-content-space-between is-align-items-center is-mb-3\">\n <he-chart-export-button [chart]=\"chart()\" [chartExportFn]=\"chartExportFn\" [exportFormats]=\"exportFormats()\" />\n\n <ng-content />\n</div>\n\n@if (terms()?.length) {\n <div class=\"is-flex is-align-items-center is-flex-wrap-wrap is-gap-12 is-mb-2 | breakdown-actions-table\">\n @if (terms()?.length) {\n <div class=\"control is-expanded is-flex-grow-1\">\n <div class=\"select is-fullwidth is-small\">\n <select [(ngModel)]=\"selectedTermId\" name=\"selectedTermId\">\n @for (term of terms(); track term['@id']) {\n <option [value]=\"term['@id']\">{{ term.name }}</option>\n }\n </select>\n </div>\n </div>\n }\n @if (methods()?.length) {\n <div class=\"control is-expanded is-flex-shrink-0\">\n <div class=\"select is-fullwidth is-small\">\n <select [(ngModel)]=\"selectedMethodId\" name=\"selectedMethodId\">\n @for (term of methods(); track term['@id']) {\n <option [value]=\"term['@id']\">{{ term.name }}</option>\n }\n </select>\n </div>\n </div>\n }\n @if (enableContributions()) {\n <div class=\"control is-expanded is-flex-shrink-0\">\n <div class=\"select is-fullwidth is-small\">\n <select [(ngModel)]=\"selectedCategory\" name=\"selectedCategory\">\n <option [ngValue]=\"undefined\">No Disaggregation</option>\n @for (category of categories; track category.key) {\n <option [value]=\"category.key\">{{ category.label }}</option>\n }\n </select>\n </div>\n </div>\n }\n </div>\n}\n\n@if (enableContributions()) {\n <he-contribution-chart\n class=\"is-relative h-100\"\n [label]=\"selectedTerm()?.units\"\n [data]=\"chartData()\"\n [labels]=\"chartLabels()\"\n [category]=\"selectedCategory()\"\n [showExportButton]=\"false\"\n [showLegend]=\"false\" />\n} @else {\n <he-horizontal-bar-chart\n class=\"is-relative h-100\"\n [title]=\"selectedTerm()?.units\"\n [data]=\"chartData()\"\n [showExportButton]=\"false\" />\n}\n", styles: [":host{display:block;overflow:visible}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: HorizontalBarChartComponent, selector: "he-horizontal-bar-chart", inputs: ["tooltipFn", "afterBarDrawSettings", "minHeight", "maxHeight"], exportAs: ["horizontalBarChart"] }, { kind: "component", type: ContributionChartComponent, selector: "he-contribution-chart", inputs: ["data", "labels", "label", "showExportButton", "showLegend", "config", "minHeight", "maxHeight", "height", "category"], exportAs: ["contributionChart"] }, { kind: "component", type: ChartExportButtonComponent, selector: "he-chart-export-button", inputs: ["buttonClass", "chart", "config", "exportFormats", "chartExportFn"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
17404
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: ImpactAssessmentsIndicatorsChartComponent, isStandalone: true, selector: "he-impact-assessments-indicators-chart", inputs: { key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: false, transformFunction: null }, filterTermTypes: { classPropertyName: "filterTermTypes", publicName: "filterTermTypes", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "barChart", first: true, predicate: HorizontalBarChartComponent, descendants: true, isSignal: true }, { propertyName: "contributionChart", first: true, predicate: ContributionChartComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"is-flex is-gap-8 is-justify-content-space-between is-align-items-center is-mb-3\">\n <he-chart-export-button [chart]=\"chart()\" [chartExportFn]=\"chartExportFn\" [exportFormats]=\"exportFormats()\" />\n\n <ng-content />\n</div>\n\n@if (terms()?.length || products()?.length > 1) {\n <div class=\"is-flex is-align-items-center is-flex-wrap-wrap is-gap-12 is-mb-2 | breakdown-actions-table\">\n @if (terms()?.length) {\n <div class=\"control is-expanded is-flex-grow-1\">\n <div class=\"select is-fullwidth is-small\">\n <select [(ngModel)]=\"selectedTermId\" name=\"selectedTermId\">\n @for (term of terms(); track term['@id']) {\n <option [value]=\"term['@id']\">{{ term.name }}</option>\n }\n </select>\n </div>\n </div>\n }\n @if (products()?.length > 1) {\n <div class=\"control is-expanded is-flex-shrink-0\">\n <div class=\"select is-fullwidth is-small\">\n <select [(ngModel)]=\"selectedProductId\" name=\"selectedProductId\">\n <option [ngValue]=\"undefined\">All products</option>\n @for (product of products(); track product['@id']) {\n <option [value]=\"product['@id']\">{{ product.name }}</option>\n }\n </select>\n </div>\n </div>\n }\n @if (methods()?.length) {\n <div class=\"control is-expanded is-flex-shrink-0\">\n <div class=\"select is-fullwidth is-small\">\n <select [(ngModel)]=\"selectedMethodId\" name=\"selectedMethodId\">\n @for (term of methods(); track term['@id']) {\n <option [value]=\"term['@id']\">{{ term.name }}</option>\n }\n </select>\n </div>\n </div>\n }\n @if (enableContributions()) {\n <div class=\"control is-expanded is-flex-shrink-0\">\n <div class=\"select is-fullwidth is-small\">\n <select [(ngModel)]=\"selectedCategory\" name=\"selectedCategory\">\n <option [ngValue]=\"undefined\">No Disaggregation</option>\n @for (category of categories; track category.key) {\n <option [value]=\"category.key\">{{ category.label }}</option>\n }\n </select>\n </div>\n </div>\n }\n </div>\n}\n\n@if (enableContributions()) {\n <he-contribution-chart\n class=\"is-relative h-100\"\n [label]=\"selectedTerm()?.units\"\n [data]=\"chartData()\"\n [labels]=\"chartLabels()\"\n [category]=\"selectedCategory()\"\n [axisTooltipFn]=\"axisTooltipFn\"\n [axisLabelClickFn]=\"axisLabelClickFn\"\n [showExportButton]=\"false\"\n [showLegend]=\"false\" />\n} @else {\n <he-horizontal-bar-chart\n class=\"is-relative h-100\"\n [title]=\"selectedTerm()?.units\"\n [data]=\"chartData()\"\n [axisTooltipFn]=\"axisTooltipFn\"\n [axisLabelClickFn]=\"axisLabelClickFn\"\n [showExportButton]=\"false\" />\n}\n", styles: [":host{display:block;overflow:visible}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: HorizontalBarChartComponent, selector: "he-horizontal-bar-chart", inputs: ["tooltipFn", "afterBarDrawSettings", "axisTooltipFn", "axisLabelClickFn", "minHeight", "maxHeight"], exportAs: ["horizontalBarChart"] }, { kind: "component", type: ContributionChartComponent, selector: "he-contribution-chart", inputs: ["data", "labels", "label", "showExportButton", "showLegend", "config", "axisTooltipFn", "axisLabelClickFn", "minHeight", "maxHeight", "height", "category"], exportAs: ["contributionChart"] }, { kind: "component", type: ChartExportButtonComponent, selector: "he-chart-export-button", inputs: ["buttonClass", "chart", "config", "exportFormats", "chartExportFn"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
17216
17405
|
}
|
|
17217
17406
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ImpactAssessmentsIndicatorsChartComponent, decorators: [{
|
|
17218
17407
|
type: Component$1,
|
|
17219
|
-
args: [{ selector: 'he-impact-assessments-indicators-chart', changeDetection: ChangeDetectionStrategy.OnPush, imports: [FormsModule, HorizontalBarChartComponent, ContributionChartComponent, ChartExportButtonComponent], template: "<div class=\"is-flex is-gap-8 is-justify-content-space-between is-align-items-center is-mb-3\">\n <he-chart-export-button [chart]=\"chart()\" [chartExportFn]=\"chartExportFn\" [exportFormats]=\"exportFormats()\" />\n\n <ng-content />\n</div>\n\n@if (terms()?.length) {\n <div class=\"is-flex is-align-items-center is-flex-wrap-wrap is-gap-12 is-mb-2 | breakdown-actions-table\">\n @if (terms()?.length) {\n <div class=\"control is-expanded is-flex-grow-1\">\n <div class=\"select is-fullwidth is-small\">\n <select [(ngModel)]=\"selectedTermId\" name=\"selectedTermId\">\n @for (term of terms(); track term['@id']) {\n <option [value]=\"term['@id']\">{{ term.name }}</option>\n }\n </select>\n </div>\n </div>\n }\n @if (methods()?.length) {\n <div class=\"control is-expanded is-flex-shrink-0\">\n <div class=\"select is-fullwidth is-small\">\n <select [(ngModel)]=\"selectedMethodId\" name=\"selectedMethodId\">\n @for (term of methods(); track term['@id']) {\n <option [value]=\"term['@id']\">{{ term.name }}</option>\n }\n </select>\n </div>\n </div>\n }\n @if (enableContributions()) {\n <div class=\"control is-expanded is-flex-shrink-0\">\n <div class=\"select is-fullwidth is-small\">\n <select [(ngModel)]=\"selectedCategory\" name=\"selectedCategory\">\n <option [ngValue]=\"undefined\">No Disaggregation</option>\n @for (category of categories; track category.key) {\n <option [value]=\"category.key\">{{ category.label }}</option>\n }\n </select>\n </div>\n </div>\n }\n </div>\n}\n\n@if (enableContributions()) {\n <he-contribution-chart\n class=\"is-relative h-100\"\n [label]=\"selectedTerm()?.units\"\n [data]=\"chartData()\"\n [labels]=\"chartLabels()\"\n [category]=\"selectedCategory()\"\n [showExportButton]=\"false\"\n [showLegend]=\"false\" />\n} @else {\n <he-horizontal-bar-chart\n class=\"is-relative h-100\"\n [title]=\"selectedTerm()?.units\"\n [data]=\"chartData()\"\n [showExportButton]=\"false\" />\n}\n", styles: [":host{display:block;overflow:visible}\n"] }]
|
|
17408
|
+
args: [{ selector: 'he-impact-assessments-indicators-chart', changeDetection: ChangeDetectionStrategy.OnPush, imports: [FormsModule, HorizontalBarChartComponent, ContributionChartComponent, ChartExportButtonComponent], template: "<div class=\"is-flex is-gap-8 is-justify-content-space-between is-align-items-center is-mb-3\">\n <he-chart-export-button [chart]=\"chart()\" [chartExportFn]=\"chartExportFn\" [exportFormats]=\"exportFormats()\" />\n\n <ng-content />\n</div>\n\n@if (terms()?.length || products()?.length > 1) {\n <div class=\"is-flex is-align-items-center is-flex-wrap-wrap is-gap-12 is-mb-2 | breakdown-actions-table\">\n @if (terms()?.length) {\n <div class=\"control is-expanded is-flex-grow-1\">\n <div class=\"select is-fullwidth is-small\">\n <select [(ngModel)]=\"selectedTermId\" name=\"selectedTermId\">\n @for (term of terms(); track term['@id']) {\n <option [value]=\"term['@id']\">{{ term.name }}</option>\n }\n </select>\n </div>\n </div>\n }\n @if (products()?.length > 1) {\n <div class=\"control is-expanded is-flex-shrink-0\">\n <div class=\"select is-fullwidth is-small\">\n <select [(ngModel)]=\"selectedProductId\" name=\"selectedProductId\">\n <option [ngValue]=\"undefined\">All products</option>\n @for (product of products(); track product['@id']) {\n <option [value]=\"product['@id']\">{{ product.name }}</option>\n }\n </select>\n </div>\n </div>\n }\n @if (methods()?.length) {\n <div class=\"control is-expanded is-flex-shrink-0\">\n <div class=\"select is-fullwidth is-small\">\n <select [(ngModel)]=\"selectedMethodId\" name=\"selectedMethodId\">\n @for (term of methods(); track term['@id']) {\n <option [value]=\"term['@id']\">{{ term.name }}</option>\n }\n </select>\n </div>\n </div>\n }\n @if (enableContributions()) {\n <div class=\"control is-expanded is-flex-shrink-0\">\n <div class=\"select is-fullwidth is-small\">\n <select [(ngModel)]=\"selectedCategory\" name=\"selectedCategory\">\n <option [ngValue]=\"undefined\">No Disaggregation</option>\n @for (category of categories; track category.key) {\n <option [value]=\"category.key\">{{ category.label }}</option>\n }\n </select>\n </div>\n </div>\n }\n </div>\n}\n\n@if (enableContributions()) {\n <he-contribution-chart\n class=\"is-relative h-100\"\n [label]=\"selectedTerm()?.units\"\n [data]=\"chartData()\"\n [labels]=\"chartLabels()\"\n [category]=\"selectedCategory()\"\n [axisTooltipFn]=\"axisTooltipFn\"\n [axisLabelClickFn]=\"axisLabelClickFn\"\n [showExportButton]=\"false\"\n [showLegend]=\"false\" />\n} @else {\n <he-horizontal-bar-chart\n class=\"is-relative h-100\"\n [title]=\"selectedTerm()?.units\"\n [data]=\"chartData()\"\n [axisTooltipFn]=\"axisTooltipFn\"\n [axisLabelClickFn]=\"axisLabelClickFn\"\n [showExportButton]=\"false\" />\n}\n", styles: [":host{display:block;overflow:visible}\n"] }]
|
|
17220
17409
|
}], ctorParameters: () => [], propDecorators: { barChart: [{ type: i0.ViewChild, args: [i0.forwardRef(() => HorizontalBarChartComponent), { isSignal: true }] }], contributionChart: [{ type: i0.ViewChild, args: [i0.forwardRef(() => ContributionChartComponent), { isSignal: true }] }], key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: false }] }], filterTermTypes: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterTermTypes", required: false }] }] } });
|
|
17221
17410
|
|
|
17222
17411
|
var View$1;
|
|
@@ -17267,6 +17456,7 @@ class ImpactAssessmentsProductsComponent {
|
|
|
17267
17456
|
this.filterTermTypes = input([], ...(ngDevMode ? [{ debugName: "filterTermTypes" }] : []));
|
|
17268
17457
|
this.enableFilterMethodModel = input(false, ...(ngDevMode ? [{ debugName: "enableFilterMethodModel" }] : []));
|
|
17269
17458
|
this.schemaBaseUrl = schemaBaseUrl();
|
|
17459
|
+
this.productTerm = impactAssessmentProduct;
|
|
17270
17460
|
this.nodeVersionKey = nodeVersionKey;
|
|
17271
17461
|
this.countGroupVisibleNodes = countGroupVisibleNodes;
|
|
17272
17462
|
this.headerKeys = computed(() => [
|
|
@@ -17362,9 +17552,6 @@ class ImpactAssessmentsProductsComponent {
|
|
|
17362
17552
|
cycleLabel({ '@id': id, name }) {
|
|
17363
17553
|
return name || this.cycles().find(v => v['@id'] === id)?.name;
|
|
17364
17554
|
}
|
|
17365
|
-
productTerm(impactAssessment) {
|
|
17366
|
-
return impactAssessment.product?.term || impactAssessment.term;
|
|
17367
|
-
}
|
|
17368
17555
|
selectIndex({ target: { value } }) {
|
|
17369
17556
|
this.selectedIndex.set(+value);
|
|
17370
17557
|
}
|
|
@@ -18065,5 +18252,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
|
|
|
18065
18252
|
* Generated bundle index. Do not edit.
|
|
18066
18253
|
*/
|
|
18067
18254
|
|
|
18068
|
-
export { ARRAY_DELIMITER, ApplyPurePipe, BarChartComponent, BibliographiesSearchConfirmComponent, BlankNodeStateComponent, BlankNodeStateNoticeComponent, BlankNodeValueDeltaComponent, CapitalizePipe, ChartComponent, ChartConfigurationDirective, ChartExportButtonComponent, ChartTooltipComponent, ClickOutsideDirective, ClipboardComponent, CollapsibleBlockComponent, CollapsibleBoxComponent, CollapsibleBoxStyle, ColorPalette, CompoundDirective, CompoundPipe, ContributionChartComponent, ControlValueAccessor, CycleNodesKeyGroup, CyclesCompletenessComponent, CyclesEmissionsCategoryService, CyclesEmissionsChartComponent, CyclesFunctionalUnitMeasureComponent, CyclesMetadataComponent, CyclesNodesComponent, CyclesNodesTimelineComponent, CyclesResultComponent, DataTableComponent, DefaultPipe, DeltaColour, DistributionChartComponent, DrawerContainerComponent, DurationPipe, EllipsisPipe, EngineModelsLinkComponent, EngineModelsLookupInfoComponent, EngineModelsStageComponent, EngineModelsStageDeepComponent, EngineModelsStageDeepService, EngineModelsVersionInfoComponent, EngineModelsVersionLinkComponent, EngineOrchestratorEditComponent, EngineRequirementsFormComponent, FileSizePipe, FileUploadErrorKeys, FilesDragDropDirective, FilesDropZoneComponent, FilesErrorSummaryComponent, FilesFormComponent, FilesFormEditableComponent, FilesUploadErrorsComponent, FilterAccordionComponent, FormulaBlockComponent, GUIDE_ENABLED, GetPipe, GlossaryMigrationFormat, GuideOverlayComponent, HE_API_BASE_URL, HE_CALCULATIONS_BASE_URL, HE_MAP_LOADED, HeAuthService, HeCommonService, HeEngineService, HeGlossaryService, HeMendeleyService, HeNodeCsvService, HeNodeService, HeNodeStoreService, HeSchemaService, HeSearchService, HeToastService, HorizontalBarChartComponent, HorizontalButtonsGroupComponent, ImpactAssessmentsGraphComponent, ImpactAssessmentsIndicatorBreakdownChartComponent, ImpactAssessmentsIndicatorsChartComponent, ImpactAssessmentsProductsComponent, IsArrayPipe, IsObjectPipe, IssueConfirmComponent, KeyToLabelPipe, Level, LineChartComponent, LinkKeyValueComponent, LogStatus, LongPressDirective, MAX_RESULTS, MapsDrawingComponent, MapsDrawingConfirmComponent, MaxPipe, MeanPipe, MedianPipe, MendeleySearchResult, MinPipe, MobileShellComponent, NavigationMenuComponent, NoExtPipe, NodeAggregatedComponent, NodeAggregatedFormulasComponent, NodeAggregatedInfoComponent, NodeAggregatedQualityScoreComponent, NodeAggregationLogsComponent, NodeCsvExportConfirmComponent, NodeCsvPreviewComponent, NodeCsvSelectHeadersComponent, NodeIconComponent, NodeJLogModelsComponent, NodeJsonldComponent, NodeJsonldSchemaComponent, NodeKeyState, NodeLinkComponent, NodeLogsFileComponent, NodeLogsModelsComponent, NodeLogsTimeComponent, NodeMissingLookupFactorsComponent, NodeQualityScore, NodeRecommendationsComponent, NodeSelectComponent, NodeValueDetailsComponent, PipelineStagesProgressComponent, PluralizePipe, PopoverComponent, PopoverConfirmComponent, PrecisionPipe, RelatedNodeResult, RemoveMarkdownPipe, RepeatPipe, Repository, ResizedDirective, ResizedEvent, ResponsiveService, SchemaInfoComponent, SchemaVersionLinkComponent, SearchExtendComponent, ShelfDialogComponent, ShellComponent, SiteNodesKeyGroup, SitesManagementChartComponent, SitesMapsComponent, SitesNodesComponent, SkeletonTextComponent, SocialTagsComponent, SortByPipe, SortSelectComponent, SumPipe, TagsInputDirective, Template, TermsPropertyContentComponent, TermsSubClassOfContentComponent, TermsUnitsDescriptionComponent, ThousandSuffixesPipe, ThousandsPipe, TimesPipe, ToastComponent, UncapitalizePipe, addPolygonToFeature, afterBarDrawPlugin, allCountriesQuery, allGroups, allOptions, availableProperties, axisHoverPlugin, backgroundHoverPlugin, backgroundModelParams, baseApiUrl, baseUrl, bottom, buildSummary, bytesSize, calculateCycleDuration, calculateCycleDurationEnabled, calculateCycleStartDate, calculateCycleStartDateEnabled, capitalize, changelogUrl, clustererImage, code, colorToRgba, compoundToHtml, computeKeys, computeTerms, contactUsEmail, contactUsLink, convertToSvg, coordinatesToPoint, copyObject, countGroupVisibleNodes, countriesQuery, createMarker, cropsQuery, d3ellipse, d3wrap, dataPathLabel, dataPathToKey, dataVersionHeader, dataVersionHeaderKey, defaultFeature, defaultLabel, defaultSuggestionType, defaultTicksFont, definitionToSchemaType, distinctUntilChangedDeep, downloadFile, downloadPng, downloadSvg, ellipsis, engineGitBaseUrl, engineGitUrl, errorText, errorsLabel, evaluateSuccess, exportAsSVG, exportFormats, externalLink, externalNodeLink, fillColor, fillStyle, filterBlankNode$1 as filterBlankNode, filterParams, findBackgroundModel, findConfigModels, findMatchingModel, findModels, findNodeModel, findOrchestratorModel, findProperty, findPropertyById, findTermModels, flatFilterData, flatFilterNode, formatCustomErrorMessage, formatDate, formatError, formatPropertyError, formatter$1 as formatter, getColor, getDatesBetween, gitBranch, gitHome, glossaryBaseUrl, glossaryLink, groupBlankNodesByTermIdentity, groupChanged, groupDataByCategory, groupJLogByField, groupJLogByTerm, groupLogsByTerm, groupNodesByTerm, groupdLogsByKey, grouppedKeys, grouppedValueKeys, groupsLogsByFields, guideModelUrl, guideNamespace, handleAPIError, handleGuideEvent, hasError, hasValidationError, hasWarning, hexToRgba, ignoreKeys$2 as ignoreKeys, increaseScaleLimits, initialFilterState, injectResizeEvent$, inputGroupsTermTypes, isAddPropertyEnabled, isChrome, isDateBetween, isEqual, isExternal, isIdenticalNodeValue, isKeyClosedVisible, isKeyHidden, isMaxStage, isMethodModelAllowed, isNonNodeModelKey, isSchemaIri, isScrolledBelow, isState, isTermTypeAllowed, isValidKey, jLogModelCount, keyToDataPath, levels, listColor, listColorContinuous, listColorWithAlpha, loadMapApi, locationQuery, logToCsv$2 as logToCsv, logValueArray, logsKey, lollipopChartPlugin, lookupUrl, mapFilterData, mapsUrl, markerIcon, markerPie, matchAggregatedQuery, matchAggregatedValidatedQuery, matchBoolPrefixQuery, matchCountry, matchExactQuery, matchGlobalRegion, matchId, matchNameNormalized, matchNestedKey, matchPhrasePrefixQuery, matchPhraseQuery, matchPrimaryProductQuery, matchQuery, matchRegex, matchRegion, matchTermType, matchType, maxAreaSize, measurementValue, mergeDataWithHeaders, methodTierOrder, migrationErrorMessage, migrationsUrl, modelCount, modelKeyParams, modelParams, models, multiMatchQuery, nestedProperty, nestingEnabled, nestingTypeEnabled, noValue, nodeAvailableProperties, nodeById, nodeColours$1 as nodeColours, nodeDataState, nodeDataStates, nodeDataVersion, nodeId, nodeIdWithoutDataVersion, nodeIds, nodeLink, nodeLinkEnabled, nodeLinkTypeEnabled, nodeLogsUrl, nodeQualityScoreColor, nodeQualityScoreLevel, nodeQualityScoreMaxDefault, nodeQualityScoreOrder, nodeRequestId, nodeSecondaryColours, nodeToAggregationFilename, nodeType, nodeTypeDataState, nodeTypeIcon, nodeTypeIconSchema, nodeUrl, nodeUrlParams, nodeVersion, nodeVersionKey, nodesByState, nodesByType, numberGte, optionsFromGroup, parentKey, parentProperty, parseColor, parseData, parseDataPath, parseLines, parseMessage, parseNewValue, pluralize, pointToCoordinates, polygonBounds, polygonToCoordinates, polygonToMap, polygonsFromFeature, populateWithTrackIdsFilterData, postGuideEvent, primaryProduct, productsQuery, propertyError, propertyId, recursiveProperties, refToSchemaType, refreshPropertyKeys, regionsQuery, registerChart, repeat, reportIssueLink, reportIssueUrl, safeJSONParse, safeJSONStringify, schemaBaseUrl, schemaDataBaseUrl, schemaLink, schemaRequiredProperties, schemaTypeToDefaultValue, scrollToEl, scrollTop, searchFilterData, searchableTypes, siblingProperty, simplifyContributions, singleProperty, siteTooBig, siteTypeToColor, siteTypeToIcon, sortProperties, sortedDates, strokeColor, strokeStyle, subValueKeys, suggestMatchQuery, suggestQuery, sumValues, takeAfterViewInit, termLocation, termLocationName, termProperties, termTypeLabel, toSnakeCase, toTextParts, toThousands, typeToNewProperty, typeaheadFocus, uncapitalize, uniqueDatesBetween, updateProperties, valueLink, valueToString, valueTypeToDefault, valueValue, waitFor, wildcardQuery };
|
|
18255
|
+
export { ARRAY_DELIMITER, ApplyPurePipe, BarChartComponent, BibliographiesSearchConfirmComponent, BlankNodeStateComponent, BlankNodeStateNoticeComponent, BlankNodeValueDeltaComponent, CapitalizePipe, ChartComponent, ChartConfigurationDirective, ChartExportButtonComponent, ChartTooltipComponent, ClickOutsideDirective, ClipboardComponent, CollapsibleBlockComponent, CollapsibleBoxComponent, CollapsibleBoxStyle, ColorPalette, CompoundDirective, CompoundPipe, ContributionChartComponent, ControlValueAccessor, CycleNodesKeyGroup, CyclesCompletenessComponent, CyclesEmissionsCategoryService, CyclesEmissionsChartComponent, CyclesFunctionalUnitMeasureComponent, CyclesMetadataComponent, CyclesNodesComponent, CyclesNodesTimelineComponent, CyclesResultComponent, DataTableComponent, DefaultPipe, DeltaColour, DistributionChartComponent, DrawerContainerComponent, DurationPipe, EllipsisPipe, EngineModelsLinkComponent, EngineModelsLookupInfoComponent, EngineModelsStageComponent, EngineModelsStageDeepComponent, EngineModelsStageDeepService, EngineModelsVersionInfoComponent, EngineModelsVersionLinkComponent, EngineOrchestratorEditComponent, EngineRequirementsFormComponent, FileSizePipe, FileUploadErrorKeys, FilesDragDropDirective, FilesDropZoneComponent, FilesErrorSummaryComponent, FilesFormComponent, FilesFormEditableComponent, FilesUploadErrorsComponent, FilterAccordionComponent, FormulaBlockComponent, GUIDE_ENABLED, GetPipe, GlossaryMigrationFormat, GuideOverlayComponent, HE_API_BASE_URL, HE_CALCULATIONS_BASE_URL, HE_MAP_LOADED, HeAuthService, HeCommonService, HeEngineService, HeGlossaryService, HeMendeleyService, HeNodeCsvService, HeNodeService, HeNodeStoreService, HeSchemaService, HeSearchService, HeToastService, HorizontalBarChartComponent, HorizontalButtonsGroupComponent, ImpactAssessmentsGraphComponent, ImpactAssessmentsIndicatorBreakdownChartComponent, ImpactAssessmentsIndicatorsChartComponent, ImpactAssessmentsProductsComponent, IsArrayPipe, IsObjectPipe, IssueConfirmComponent, KeyToLabelPipe, Level, LineChartComponent, LinkKeyValueComponent, LogStatus, LongPressDirective, MAX_RESULTS, MapsDrawingComponent, MapsDrawingConfirmComponent, MaxPipe, MeanPipe, MedianPipe, MendeleySearchResult, MinPipe, MobileShellComponent, NavigationMenuComponent, NoExtPipe, NodeAggregatedComponent, NodeAggregatedFormulasComponent, NodeAggregatedInfoComponent, NodeAggregatedQualityScoreComponent, NodeAggregationLogsComponent, NodeCsvExportConfirmComponent, NodeCsvPreviewComponent, NodeCsvSelectHeadersComponent, NodeIconComponent, NodeJLogModelsComponent, NodeJsonldComponent, NodeJsonldSchemaComponent, NodeKeyState, NodeLinkComponent, NodeLogsFileComponent, NodeLogsModelsComponent, NodeLogsTimeComponent, NodeMissingLookupFactorsComponent, NodeQualityScore, NodeRecommendationsComponent, NodeSelectComponent, NodeValueDetailsComponent, PipelineStagesProgressComponent, PluralizePipe, PopoverComponent, PopoverConfirmComponent, PrecisionPipe, RelatedNodeResult, RemoveMarkdownPipe, RepeatPipe, Repository, ResizedDirective, ResizedEvent, ResponsiveService, SchemaInfoComponent, SchemaVersionLinkComponent, SearchExtendComponent, ShelfDialogComponent, ShellComponent, SiteNodesKeyGroup, SitesManagementChartComponent, SitesMapsComponent, SitesNodesComponent, SkeletonTextComponent, SocialTagsComponent, SortByPipe, SortSelectComponent, SumPipe, TagsInputDirective, Template, TermsPropertyContentComponent, TermsSubClassOfContentComponent, TermsUnitsDescriptionComponent, ThousandSuffixesPipe, ThousandsPipe, TimesPipe, ToastComponent, UncapitalizePipe, addPolygonToFeature, afterBarDrawPlugin, allCountriesQuery, allGroups, allOptions, availableProperties, axisHoverPlugin, axisLabelCursor, axisLabelSettings, backgroundHoverPlugin, backgroundModelParams, baseApiUrl, baseUrl, bottom, buildSummary, bytesSize, calculateCycleDuration, calculateCycleDurationEnabled, calculateCycleStartDate, calculateCycleStartDateEnabled, capitalize, changelogUrl, chartLabelMaxLength, clustererImage, code, colorToRgba, compoundToHtml, computeKeys, computeTerms, contactUsEmail, contactUsLink, convertToSvg, coordinatesToPoint, copyObject, countGroupVisibleNodes, countriesQuery, createMarker, cropsQuery, d3ellipse, d3wrap, dataPathLabel, dataPathToKey, dataVersionHeader, dataVersionHeaderKey, defaultFeature, defaultLabel, defaultSuggestionType, defaultTicksFont, definitionToSchemaType, distinctUntilChangedDeep, downloadFile, downloadPng, downloadSvg, ellipsis, engineGitBaseUrl, engineGitUrl, errorText, errorsLabel, evaluateSuccess, exportAsSVG, exportFormats, externalLink, externalNodeLink, fillColor, fillStyle, filterBlankNode$1 as filterBlankNode, filterParams, findBackgroundModel, findConfigModels, findMatchingModel, findModels, findNodeModel, findOrchestratorModel, findProperty, findPropertyById, findTermModels, flatFilterData, flatFilterNode, formatCustomErrorMessage, formatDate, formatError, formatPropertyError, formatter$1 as formatter, getColor, getDatesBetween, gitBranch, gitHome, glossaryBaseUrl, glossaryLink, groupBlankNodesByTermIdentity, groupChanged, groupDataByCategory, groupJLogByField, groupJLogByTerm, groupLogsByTerm, groupNodesByTerm, groupdLogsByKey, grouppedKeys, grouppedValueKeys, groupsLogsByFields, guideModelUrl, guideNamespace, handleAPIError, handleGuideEvent, hasError, hasValidationError, hasWarning, hexToRgba, highestMethodTier, ignoreKeys$2 as ignoreKeys, impactAssessmentProduct, increaseScaleLimits, initialFilterState, injectResizeEvent$, inputGroupsTermTypes, isAddPropertyEnabled, isChrome, isDateBetween, isEqual, isExternal, isIdenticalNodeValue, isKeyClosedVisible, isKeyHidden, isMaxStage, isMethodModelAllowed, isNonNodeModelKey, isSchemaIri, isScrolledBelow, isState, isTermTypeAllowed, isValidKey, jLogModelCount, keyToDataPath, levels, listColor, listColorContinuous, listColorWithAlpha, loadMapApi, locationQuery, logToCsv$2 as logToCsv, logValueArray, logsKey, lollipopChartPlugin, lookupUrl, mapFilterData, mapsUrl, markerIcon, markerPie, matchAggregatedQuery, matchAggregatedValidatedQuery, matchBoolPrefixQuery, matchCountry, matchExactQuery, matchGlobalRegion, matchId, matchNameNormalized, matchNestedKey, matchPhrasePrefixQuery, matchPhraseQuery, matchPrimaryProductQuery, matchQuery, matchRegex, matchRegion, matchTermType, matchType, maxAreaSize, measurementValue, mergeDataWithHeaders, methodTierOrder, migrationErrorMessage, migrationsUrl, modelCount, modelKeyParams, modelParams, models, multiMatchQuery, nestedProperty, nestingEnabled, nestingTypeEnabled, noValue, nodeAvailableProperties, nodeById, nodeChartLabels, nodeColours$1 as nodeColours, nodeDataState, nodeDataStates, nodeDataVersion, nodeId, nodeIdWithoutDataVersion, nodeIds, nodeLink, nodeLinkEnabled, nodeLinkTypeEnabled, nodeLogsUrl, nodeQualityScoreColor, nodeQualityScoreLevel, nodeQualityScoreMaxDefault, nodeQualityScoreOrder, nodeRequestId, nodeSecondaryColours, nodeToAggregationFilename, nodeType, nodeTypeDataState, nodeTypeIcon, nodeTypeIconSchema, nodeUrl, nodeUrlParams, nodeVersion, nodeVersionKey, nodesByState, nodesByType, numberGte, openNodeUrl, openUrl, optionsFromGroup, parentKey, parentProperty, parseColor, parseData, parseDataPath, parseLines, parseMessage, parseNewValue, pluralize, pointToCoordinates, polygonBounds, polygonToCoordinates, polygonToMap, polygonsFromFeature, populateWithTrackIdsFilterData, postGuideEvent, primaryProduct, productsQuery, propertyError, propertyId, recursiveProperties, refToSchemaType, refreshPropertyKeys, regionsQuery, registerChart, repeat, reportIssueLink, reportIssueUrl, safeJSONParse, safeJSONStringify, schemaBaseUrl, schemaDataBaseUrl, schemaLink, schemaRequiredProperties, schemaTypeToDefaultValue, scrollToEl, scrollTop, searchFilterData, searchableTypes, siblingProperty, simplifyContributions, singleProperty, siteTooBig, siteTypeToColor, siteTypeToIcon, sortProperties, sortedDates, strokeColor, strokeStyle, subValueKeys, suggestMatchQuery, suggestQuery, suggestTerms, sumValues, takeAfterViewInit, termLocation, termLocationName, termProperties, termSearch, termTypeLabel, toSnakeCase, toTextParts, toThousands, typeToNewProperty, typeaheadFocus, uncapitalize, uniqueDatesBetween, updateProperties, valueLink, valueToString, valueTypeToDefault, valueValue, waitFor, wildcardQuery };
|
|
18069
18256
|
//# sourceMappingURL=hestia-earth-ui-components.mjs.map
|