@c8y/ngx-components 1023.48.2 → 1023.50.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/asset-properties/index.d.ts +1 -2
- package/asset-properties/index.d.ts.map +1 -1
- package/context-dashboard/index.d.ts +2 -1
- package/context-dashboard/index.d.ts.map +1 -1
- package/echart/index.d.ts +5 -2
- package/echart/index.d.ts.map +1 -1
- package/fesm2022/c8y-ngx-components-asset-properties.mjs +3 -4
- package/fesm2022/c8y-ngx-components-asset-properties.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-context-dashboard.mjs +12 -9
- package/fesm2022/c8y-ngx-components-context-dashboard.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-device-grid.mjs +1 -1
- package/fesm2022/c8y-ngx-components-device-grid.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-echart.mjs +96 -42
- package/fesm2022/c8y-ngx-components-echart.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-asset-table.mjs +127 -0
- package/fesm2022/c8y-ngx-components-widgets-definitions-asset-table.mjs.map +1 -0
- package/fesm2022/c8y-ngx-components-widgets-definitions-datapoints-graph.mjs +3 -3
- package/fesm2022/c8y-ngx-components-widgets-definitions-datapoints-graph.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions.mjs +1 -0
- package/fesm2022/c8y-ngx-components-widgets-definitions.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-exports.mjs +8 -1
- package/fesm2022/c8y-ngx-components-widgets-exports.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-implementations-asset-table.mjs +1959 -0
- package/fesm2022/c8y-ngx-components-widgets-implementations-asset-table.mjs.map +1 -0
- package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-graph.mjs +55 -51
- package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-graph.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components.mjs +323 -164
- package/fesm2022/c8y-ngx-components.mjs.map +1 -1
- package/index.d.ts +150 -8
- package/index.d.ts.map +1 -1
- package/locales/de.po +204 -0
- package/locales/es.po +204 -0
- package/locales/fr.po +204 -0
- package/locales/ja_JP.po +204 -0
- package/locales/ko.po +204 -0
- package/locales/locales.pot +204 -0
- package/locales/nl.po +204 -0
- package/locales/pl.po +204 -0
- package/locales/pt_BR.po +204 -0
- package/locales/zh_CN.po +204 -0
- package/locales/zh_TW.po +204 -0
- package/package.json +1 -1
- package/widgets/cockpit-exports/index.d.ts +6 -0
- package/widgets/cockpit-exports/index.d.ts.map +1 -1
- package/widgets/definitions/asset-table/index.d.ts +6 -0
- package/widgets/definitions/asset-table/index.d.ts.map +1 -0
- package/widgets/definitions/index.d.ts +1 -0
- package/widgets/definitions/index.d.ts.map +1 -1
- package/widgets/device-management-exports/index.d.ts +6 -0
- package/widgets/device-management-exports/index.d.ts.map +1 -1
- package/widgets/exports/index.d.ts +8 -1
- package/widgets/exports/index.d.ts.map +1 -1
- package/widgets/implementations/asset-table/index.d.ts +229 -0
- package/widgets/implementations/asset-table/index.d.ts.map +1 -0
- package/widgets/implementations/datapoints-graph/index.d.ts +6 -3
- package/widgets/implementations/datapoints-graph/index.d.ts.map +1 -1
|
@@ -737,8 +737,8 @@ class EchartsOptionsService {
|
|
|
737
737
|
}, []);
|
|
738
738
|
// Construct series with markPoint
|
|
739
739
|
const seriesWithMarkPoint = {
|
|
740
|
-
id: `${type}/${dp.__target?.id}
|
|
741
|
-
name: `${type}-markPoint`,
|
|
740
|
+
id: `${type}/${dp.__target?.id}${id ? '+' + id : ''}-markPoint`,
|
|
741
|
+
name: `${type}/${dp.__target?.id}-markPoint`,
|
|
742
742
|
typeOfSeries: itemType,
|
|
743
743
|
data: mainData,
|
|
744
744
|
isDpTemplateSelected,
|
|
@@ -755,8 +755,8 @@ class EchartsOptionsService {
|
|
|
755
755
|
const markLineData = this.createMarkLine(itemsOfType, itemType);
|
|
756
756
|
// Construct series with markLine
|
|
757
757
|
const seriesWithMarkLine = {
|
|
758
|
-
id: `${type}/${dp.__target?.id}
|
|
759
|
-
name: `${type}-markLine`,
|
|
758
|
+
id: `${type}/${dp.__target?.id}${id ? '+' + id : ''}-markLine`,
|
|
759
|
+
name: `${type}/${dp.__target?.id}-markLine`,
|
|
760
760
|
typeOfSeries: itemType,
|
|
761
761
|
isDpTemplateSelected,
|
|
762
762
|
data: mainData,
|
|
@@ -1518,9 +1518,11 @@ class ChartRealtimeService {
|
|
|
1518
1518
|
this.pendingAlarmsOrEvents = new Map();
|
|
1519
1519
|
this.currentAlarms = [];
|
|
1520
1520
|
this.currentEvents = [];
|
|
1521
|
+
this.activeDatapoints = [];
|
|
1521
1522
|
}
|
|
1522
1523
|
startRealtime(echartsInstance, datapoints, timeRange, datapointOutOfSyncCallback, timeRangeChangedCallback, alarmOrEventConfig = [], displayOptions, alarms, events) {
|
|
1523
1524
|
this.echartsInstance = echartsInstance;
|
|
1525
|
+
this.activeDatapoints = datapoints;
|
|
1524
1526
|
this.currentTimeRange = {
|
|
1525
1527
|
dateFrom: new Date(timeRange.dateFrom),
|
|
1526
1528
|
dateTo: new Date(timeRange.dateTo)
|
|
@@ -1609,7 +1611,9 @@ class ChartRealtimeService {
|
|
|
1609
1611
|
});
|
|
1610
1612
|
this.realtimeSubscriptionAlarmsEvents = allAlarmsAndEvents$
|
|
1611
1613
|
.pipe(map(alarmOrEvent => {
|
|
1612
|
-
|
|
1614
|
+
// Match by both type AND device source
|
|
1615
|
+
const foundAlarmOrEvent = activeAlarmsOrEvents.find(aOrE => aOrE.filters.type === alarmOrEvent.type &&
|
|
1616
|
+
aOrE.__target?.id === alarmOrEvent.source?.id);
|
|
1613
1617
|
if (foundAlarmOrEvent) {
|
|
1614
1618
|
alarmOrEvent['color'] = foundAlarmOrEvent.color;
|
|
1615
1619
|
alarmOrEvent['selectedDatapoint'] = foundAlarmOrEvent.selectedDatapoint;
|
|
@@ -1677,6 +1681,7 @@ class ChartRealtimeService {
|
|
|
1677
1681
|
seriesDataToUpdate.get(datapoint)?.push(measurement);
|
|
1678
1682
|
});
|
|
1679
1683
|
let allDataSeries = this.echartsInstance?.getOption()['series'];
|
|
1684
|
+
// Process measurements for each datapoint
|
|
1680
1685
|
seriesDataToUpdate.forEach((measurements, datapoint) => {
|
|
1681
1686
|
const newValues = measurements.map(m => [
|
|
1682
1687
|
m.time,
|
|
@@ -1690,46 +1695,80 @@ class ChartRealtimeService {
|
|
|
1690
1695
|
const seriesDataToUpdate = seriesMatchingDatapoint['data'];
|
|
1691
1696
|
seriesDataToUpdate.push(...newValues);
|
|
1692
1697
|
seriesMatchingDatapoint['data'] = this.removeValuesBeforeTimeRange(seriesMatchingDatapoint);
|
|
1693
|
-
|
|
1698
|
+
this.checkForValuesAfterTimeRange(seriesMatchingDatapoint['data'], datapoint, datapointOutOfSyncCallback);
|
|
1699
|
+
});
|
|
1700
|
+
// Process alarm/event OUTSIDE the measurement loop.
|
|
1701
|
+
// Previously this was inside seriesDataToUpdate.forEach(), which meant alarms/events
|
|
1702
|
+
// were only processed when measurements existed for that datapoint. This caused
|
|
1703
|
+
// alarms/events to not appear on the chart when no measurements arrived in the interval.
|
|
1704
|
+
if (alarmOrEvent) {
|
|
1705
|
+
// The alarm config's selectedDatapoint is a partial object { target, fragment, series },
|
|
1706
|
+
// not a full DatapointsGraphKPIDetails. We need to find the matching full datapoint.
|
|
1707
|
+
const selectedDp = alarmOrEvent['selectedDatapoint'];
|
|
1708
|
+
// Find the correct datapoint to position this alarm/event on the chart:
|
|
1709
|
+
// 1. Use selectedDatapoint from alarm config (user-configured)
|
|
1710
|
+
// 2. Match by alarm's source device ID
|
|
1711
|
+
// 3. Fall back to first datapoint
|
|
1712
|
+
let datapoint = selectedDp
|
|
1713
|
+
? this.activeDatapoints.find(dp => dp.__target?.id === selectedDp.target &&
|
|
1714
|
+
dp.fragment === selectedDp.fragment &&
|
|
1715
|
+
dp.series === selectedDp.series)
|
|
1716
|
+
: undefined;
|
|
1717
|
+
if (!datapoint && alarmOrEvent['source']?.id) {
|
|
1718
|
+
datapoint = this.activeDatapoints.find(dp => dp.__target?.id === alarmOrEvent['source'].id);
|
|
1719
|
+
}
|
|
1720
|
+
if (!datapoint) {
|
|
1721
|
+
datapoint = this.activeDatapoints[0];
|
|
1722
|
+
}
|
|
1723
|
+
if (datapoint) {
|
|
1724
|
+
const datapointId = datapoint.__target?.id + datapoint.fragment + datapoint.series;
|
|
1725
|
+
const matchingSeries = allDataSeries.find(s => s['datapointId'] === datapointId);
|
|
1726
|
+
const seriesData = matchingSeries ? matchingSeries['data'] : [];
|
|
1727
|
+
// Convert ECharts series data format to the format expected by getAlarmOrEventSeries.
|
|
1728
|
+
// ECharts: [[timestamp, value], ...] → Expected: { [timestamp]: [{min, max}] }
|
|
1729
|
+
const values = {};
|
|
1730
|
+
seriesData.forEach(([timestamp, value]) => {
|
|
1731
|
+
values[timestamp] = [{ min: value, max: value }];
|
|
1732
|
+
});
|
|
1694
1733
|
const renderType = datapoint.renderType || 'min';
|
|
1695
1734
|
const dp = {
|
|
1696
1735
|
...datapoint,
|
|
1697
|
-
values
|
|
1736
|
+
values
|
|
1698
1737
|
};
|
|
1699
1738
|
if (isEvent(alarmOrEvent)) {
|
|
1700
|
-
// if event
|
|
1701
|
-
const eventExists = allDataSeries.some(series => series['data']
|
|
1739
|
+
// Check if event already exists on chart to avoid duplicates
|
|
1740
|
+
const eventExists = allDataSeries.some(series => series['data']?.some(data => data[0] === alarmOrEvent.creationTime));
|
|
1702
1741
|
if (eventExists) {
|
|
1703
1742
|
return;
|
|
1704
1743
|
}
|
|
1744
|
+
// For events, pass creationTime as unique id to create unique series per event.
|
|
1745
|
+
// This allows multiple events of the same type/device to coexist on the chart.
|
|
1746
|
+
// Series ID will be: eventType/deviceId+creationTime-markPoint
|
|
1705
1747
|
const newEventSeries = this.echartsOptionsService.getAlarmOrEventSeries(dp, renderType, false, [alarmOrEvent], 'event', displayOptions, alarmOrEvent.creationTime, null, true);
|
|
1706
1748
|
allDataSeries.push(...newEventSeries);
|
|
1707
1749
|
}
|
|
1708
1750
|
else if (isAlarm(alarmOrEvent)) {
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1751
|
+
// For alarms, remove existing series for this alarm type + device before adding.
|
|
1752
|
+
// This ensures alarm status changes (e.g., ACTIVE → CLEARED) are reflected.
|
|
1753
|
+
// Series ID format: ${alarmType}/${deviceId}-markPoint/markLine
|
|
1754
|
+
const alarm = alarmOrEvent;
|
|
1755
|
+
const alarmType = alarm.type;
|
|
1756
|
+
const datapointTargetId = datapoint.__target?.id;
|
|
1757
|
+
allDataSeries = allDataSeries.filter((series) => {
|
|
1758
|
+
const seriesId = series['id'];
|
|
1759
|
+
return !seriesId?.startsWith(`${alarmType}/${datapointTargetId}`);
|
|
1712
1760
|
});
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
// remove all matching alarm series which are in the array
|
|
1719
|
-
alarmSeries.forEach(series => {
|
|
1720
|
-
allDataSeries = allDataSeries.filter(s => s['id'] !== series['id']);
|
|
1721
|
-
});
|
|
1722
|
-
const newAlarmSeries = this.echartsOptionsService.getAlarmOrEventSeries(dp, renderType, false, [alarmOrEvent], 'alarm', displayOptions, alarmOrEvent.creationTime, null, true);
|
|
1723
|
-
allDataSeries.push(...newAlarmSeries);
|
|
1724
|
-
}
|
|
1725
|
-
else {
|
|
1726
|
-
const newAlarmSeries = this.echartsOptionsService.getAlarmOrEventSeries(dp, renderType, false, [alarmOrEvent], 'alarm', displayOptions, alarmOrEvent.id, null, true);
|
|
1727
|
-
allDataSeries.push(...newAlarmSeries);
|
|
1728
|
-
}
|
|
1761
|
+
// For alarms, pass null as id - we want one series per alarm type/device.
|
|
1762
|
+
// Series ID will be: alarmType/deviceId-markPoint (no unique suffix).
|
|
1763
|
+
// We already removed the old series above, so this replaces it.
|
|
1764
|
+
const newAlarmSeries = this.echartsOptionsService.getAlarmOrEventSeries(dp, renderType, false, [alarm], 'alarm', displayOptions, null, null, true);
|
|
1765
|
+
allDataSeries.push(...newAlarmSeries);
|
|
1729
1766
|
}
|
|
1730
1767
|
}
|
|
1731
|
-
|
|
1732
|
-
|
|
1768
|
+
}
|
|
1769
|
+
// Use replaceMerge for series to ensure removed alarm series don't persist.
|
|
1770
|
+
// Without this, ECharts merges the new series array with existing ones,
|
|
1771
|
+
// which can leave stale alarm/event series on the chart.
|
|
1733
1772
|
this.echartsInstance?.setOption({
|
|
1734
1773
|
dataZoom: [
|
|
1735
1774
|
{
|
|
@@ -1742,7 +1781,7 @@ class ChartRealtimeService {
|
|
|
1742
1781
|
max: this.currentTimeRange?.dateTo
|
|
1743
1782
|
},
|
|
1744
1783
|
series: allDataSeries
|
|
1745
|
-
});
|
|
1784
|
+
}, { replaceMerge: ['series'] });
|
|
1746
1785
|
}
|
|
1747
1786
|
/**
|
|
1748
1787
|
* Detects if a datapoint has measurements with future timestamps (out-of-sync).
|
|
@@ -2254,6 +2293,7 @@ class ChartsComponent {
|
|
|
2254
2293
|
}
|
|
2255
2294
|
/**
|
|
2256
2295
|
* Toggles the visibility of a series in the chart based on the provided datapoint.
|
|
2296
|
+
* Uses explicit legendSelect/legendUnSelect based on __active state.
|
|
2257
2297
|
* @param datapoint - The datapoint to toggle visibility for.
|
|
2258
2298
|
*/
|
|
2259
2299
|
toggleDatapointSeriesVisibility(datapoint) {
|
|
@@ -2261,26 +2301,40 @@ class ChartsComponent {
|
|
|
2261
2301
|
const seriesToUpdate = series.find(s => s.datapointId === `${datapoint.__target?.id}${datapoint.fragment}${datapoint.series}`);
|
|
2262
2302
|
if (seriesToUpdate) {
|
|
2263
2303
|
this.echartsInstance.dispatchAction({
|
|
2264
|
-
type: '
|
|
2304
|
+
type: datapoint.__active ? 'legendSelect' : 'legendUnSelect',
|
|
2265
2305
|
name: seriesToUpdate.name
|
|
2266
2306
|
});
|
|
2267
2307
|
}
|
|
2268
2308
|
}
|
|
2269
2309
|
/**
|
|
2270
|
-
* Toggles the visibility of
|
|
2310
|
+
* Toggles the visibility of alarm/event series in the chart.
|
|
2311
|
+
* Uses explicit legendSelect/legendUnSelect based on __hidden state.
|
|
2312
|
+
* Targets specific device's series using type + deviceId.
|
|
2271
2313
|
* @param alarmOrEvent - The alarm or event to toggle visibility for.
|
|
2272
2314
|
*/
|
|
2273
2315
|
toggleAlarmEventSeriesVisibility(alarmOrEvent) {
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
if (seriesToUpdate) {
|
|
2277
|
-
seriesToUpdate.forEach(s => {
|
|
2278
|
-
this.echartsInstance.dispatchAction({
|
|
2279
|
-
type: 'legendToggleSelect',
|
|
2280
|
-
name: s.name
|
|
2281
|
-
});
|
|
2282
|
-
});
|
|
2316
|
+
if (!this.echartsInstance) {
|
|
2317
|
+
return;
|
|
2283
2318
|
}
|
|
2319
|
+
const options = this.echartsInstance.getOption();
|
|
2320
|
+
const allSeries = options.series;
|
|
2321
|
+
if (!allSeries || allSeries.length === 0) {
|
|
2322
|
+
return;
|
|
2323
|
+
}
|
|
2324
|
+
const type = alarmOrEvent.filters.type;
|
|
2325
|
+
const deviceId = alarmOrEvent.__target?.id;
|
|
2326
|
+
const actionType = alarmOrEvent.__hidden ? 'legendUnSelect' : 'legendSelect';
|
|
2327
|
+
// Series names are: ${type}/${deviceId}-markPoint and ${type}/${deviceId}-markLine
|
|
2328
|
+
const markPointName = `${type}/${deviceId}-markPoint`;
|
|
2329
|
+
const markLineName = `${type}/${deviceId}-markLine`;
|
|
2330
|
+
// Find series matching this specific alarm type + device
|
|
2331
|
+
const matchingSeries = allSeries.filter(s => s.name === markPointName || s.name === markLineName);
|
|
2332
|
+
matchingSeries.forEach(series => {
|
|
2333
|
+
this.echartsInstance.dispatchAction({
|
|
2334
|
+
type: actionType,
|
|
2335
|
+
name: series.name
|
|
2336
|
+
});
|
|
2337
|
+
});
|
|
2284
2338
|
}
|
|
2285
2339
|
getDefaultChartOptions() {
|
|
2286
2340
|
return {
|