@red-hat-developer-hub/plugin-cost-management 2.0.3-rc.4

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.
Files changed (97) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/README.md +152 -0
  3. package/app-config.dynamic.yaml +28 -0
  4. package/dist/Router.esm.js +21 -0
  5. package/dist/Router.esm.js.map +1 -0
  6. package/dist/apis.esm.js +14 -0
  7. package/dist/apis.esm.js.map +1 -0
  8. package/dist/components/BasePage.esm.js +29 -0
  9. package/dist/components/BasePage.esm.js.map +1 -0
  10. package/dist/components/InfoCardTitle.esm.js +9 -0
  11. package/dist/components/InfoCardTitle.esm.js.map +1 -0
  12. package/dist/components/PageLayout.esm.js +56 -0
  13. package/dist/components/PageLayout.esm.js.map +1 -0
  14. package/dist/components/filtersStyles.esm.js +32 -0
  15. package/dist/components/filtersStyles.esm.js.map +1 -0
  16. package/dist/components/icon/AnalyticsIcon.esm.js +11 -0
  17. package/dist/components/icon/AnalyticsIcon.esm.js.map +1 -0
  18. package/dist/components/icon/AnalyticsIconFilled.esm.js +9 -0
  19. package/dist/components/icon/AnalyticsIconFilled.esm.js.map +1 -0
  20. package/dist/components/icon/AnalyticsIconOutlined.esm.js +9 -0
  21. package/dist/components/icon/AnalyticsIconOutlined.esm.js.map +1 -0
  22. package/dist/components/icon/CostManagementIcon.esm.js +11 -0
  23. package/dist/components/icon/CostManagementIcon.esm.js.map +1 -0
  24. package/dist/components/icon/CostManagementIconFilled.esm.js +9 -0
  25. package/dist/components/icon/CostManagementIconFilled.esm.js.map +1 -0
  26. package/dist/components/icon/CostManagementIconOutlined.esm.js +9 -0
  27. package/dist/components/icon/CostManagementIconOutlined.esm.js.map +1 -0
  28. package/dist/constants/currencies.esm.js +36 -0
  29. package/dist/constants/currencies.esm.js.map +1 -0
  30. package/dist/hooks/usePatternFlyTheme.esm.js +22 -0
  31. package/dist/hooks/usePatternFlyTheme.esm.js.map +1 -0
  32. package/dist/hooks/useThemeBackgroundColor.esm.js +13 -0
  33. package/dist/hooks/useThemeBackgroundColor.esm.js.map +1 -0
  34. package/dist/index.d.ts +71 -0
  35. package/dist/index.esm.js +9 -0
  36. package/dist/index.esm.js.map +1 -0
  37. package/dist/pages/openshift/OpenShiftPage.esm.js +727 -0
  38. package/dist/pages/openshift/OpenShiftPage.esm.js.map +1 -0
  39. package/dist/pages/openshift/components/AutocompleteComponent.esm.js +65 -0
  40. package/dist/pages/openshift/components/AutocompleteComponent.esm.js.map +1 -0
  41. package/dist/pages/openshift/components/DownloadIconButton.esm.js +49 -0
  42. package/dist/pages/openshift/components/DownloadIconButton.esm.js.map +1 -0
  43. package/dist/pages/openshift/components/Filters.esm.js +360 -0
  44. package/dist/pages/openshift/components/Filters.esm.js.map +1 -0
  45. package/dist/pages/openshift/components/PageHeader.esm.js +31 -0
  46. package/dist/pages/openshift/components/PageHeader.esm.js.map +1 -0
  47. package/dist/pages/openshift/components/SelectComponent.esm.js +68 -0
  48. package/dist/pages/openshift/components/SelectComponent.esm.js.map +1 -0
  49. package/dist/pages/openshift/components/TableToolbar.esm.js +249 -0
  50. package/dist/pages/openshift/components/TableToolbar.esm.js.map +1 -0
  51. package/dist/pages/optimizations/OptimizationsPage.esm.js +205 -0
  52. package/dist/pages/optimizations/OptimizationsPage.esm.js.map +1 -0
  53. package/dist/pages/optimizations/components/ComboBox.esm.js +84 -0
  54. package/dist/pages/optimizations/components/ComboBox.esm.js.map +1 -0
  55. package/dist/pages/optimizations/components/Filters.esm.js +59 -0
  56. package/dist/pages/optimizations/components/Filters.esm.js.map +1 -0
  57. package/dist/pages/optimizations/components/TableToolbar.esm.js +40 -0
  58. package/dist/pages/optimizations/components/TableToolbar.esm.js.map +1 -0
  59. package/dist/pages/optimizations-breakdown/OptimizationsBreakdownPage.esm.js +211 -0
  60. package/dist/pages/optimizations-breakdown/OptimizationsBreakdownPage.esm.js.map +1 -0
  61. package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/OptimizationEngineTab.esm.js +132 -0
  62. package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/OptimizationEngineTab.esm.js.map +1 -0
  63. package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/components/CodeInfoCard.esm.js +37 -0
  64. package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/components/CodeInfoCard.esm.js.map +1 -0
  65. package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/components/ContainerInfoCard.esm.js +50 -0
  66. package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/components/ContainerInfoCard.esm.js.map +1 -0
  67. package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/components/chart-info-card/ChartInfoCard.esm.js +26 -0
  68. package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/components/chart-info-card/ChartInfoCard.esm.js.map +1 -0
  69. package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/components/chart-info-card/components/IntlBreakdownChart.esm.js +51 -0
  70. package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/components/chart-info-card/components/IntlBreakdownChart.esm.js.map +1 -0
  71. package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/components/chart-info-card/components/intl-breakdown-chart/components/optimizations-breakdown-chart/components/optimizations-breakdown-chart/OptimizationsBreakdownChart.esm.js +388 -0
  72. package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/components/chart-info-card/components/intl-breakdown-chart/components/optimizations-breakdown-chart/components/optimizations-breakdown-chart/OptimizationsBreakdownChart.esm.js.map +1 -0
  73. package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/components/chart-info-card/components/intl-breakdown-chart/components/optimizations-breakdown-chart/components/optimizations-breakdown-chart/i18n/data.json.esm.js +512 -0
  74. package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/components/chart-info-card/components/intl-breakdown-chart/components/optimizations-breakdown-chart/components/optimizations-breakdown-chart/i18n/data.json.esm.js.map +1 -0
  75. package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/components/chart-info-card/components/intl-breakdown-chart/components/optimizations-breakdown-chart/components/optimizations-breakdown-chart/i18n/intl.esm.js +18 -0
  76. package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/components/chart-info-card/components/intl-breakdown-chart/components/optimizations-breakdown-chart/components/optimizations-breakdown-chart/i18n/intl.esm.js.map +1 -0
  77. package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/components/chart-info-card/components/intl-breakdown-chart/components/optimizations-breakdown-chart/components/optimizations-breakdown-chart/i18n/messages.esm.js +72 -0
  78. package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/components/chart-info-card/components/intl-breakdown-chart/components/optimizations-breakdown-chart/components/optimizations-breakdown-chart/i18n/messages.esm.js.map +1 -0
  79. package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/components/chart-info-card/components/intl-breakdown-chart/components/optimizations-breakdown-chart/components/optimizations-breakdown-chart/utils/chart-data-format.esm.js +96 -0
  80. package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/components/chart-info-card/components/intl-breakdown-chart/components/optimizations-breakdown-chart/components/optimizations-breakdown-chart/utils/chart-data-format.esm.js.map +1 -0
  81. package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/components/chart-info-card/components/intl-breakdown-chart/components/optimizations-breakdown-chart/components/optimizations-breakdown-chart/utils/chart-datum.esm.js +74 -0
  82. package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/components/chart-info-card/components/intl-breakdown-chart/components/optimizations-breakdown-chart/components/optimizations-breakdown-chart/utils/chart-datum.esm.js.map +1 -0
  83. package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/components/chart-info-card/components/intl-breakdown-chart/components/optimizations-breakdown-chart/components/optimizations-breakdown-chart/utils/chart-utils.esm.js +109 -0
  84. package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/components/chart-info-card/components/intl-breakdown-chart/components/optimizations-breakdown-chart/components/optimizations-breakdown-chart/utils/chart-utils.esm.js.map +1 -0
  85. package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/components/chart-info-card/components/intl-breakdown-chart/components/optimizations-breakdown-chart/components/optimizations-breakdown-chart/utils/format.esm.js +25 -0
  86. package/dist/pages/optimizations-breakdown/components/optimization-engine-tab/components/chart-info-card/components/intl-breakdown-chart/components/optimizations-breakdown-chart/components/optimizations-breakdown-chart/utils/format.esm.js.map +1 -0
  87. package/dist/pages/optimizations-breakdown/models/ChartEnums.esm.js +23 -0
  88. package/dist/pages/optimizations-breakdown/models/ChartEnums.esm.js.map +1 -0
  89. package/dist/pages/optimizations-breakdown/models/YamlCodeData.esm.js +129 -0
  90. package/dist/pages/optimizations-breakdown/models/YamlCodeData.esm.js.map +1 -0
  91. package/dist/plugin.esm.js +73 -0
  92. package/dist/plugin.esm.js.map +1 -0
  93. package/dist/routes.esm.js +16 -0
  94. package/dist/routes.esm.js.map +1 -0
  95. package/dist/utils/dates.esm.js +37 -0
  96. package/dist/utils/dates.esm.js.map +1 -0
  97. package/package.json +110 -0
@@ -0,0 +1,388 @@
1
+ import React, { useState, useCallback, useMemo, useEffect } from 'react';
2
+ import { useIntl } from 'react-intl';
3
+ import { makeStyles } from '@material-ui/core/styles';
4
+ import { createContainer, Chart, ChartThemeColor, ChartAxis, ChartLegend, getInteractiveLegendEvents, ChartLegendTooltip, ChartArea, ChartScatter, ChartBoxPlot } from '@patternfly/react-charts/victory';
5
+ import { chart_color_blue_100 } from '@patternfly/react-tokens/dist/js/chart_color_blue_100';
6
+ import { chart_color_blue_200 } from '@patternfly/react-tokens/dist/js/chart_color_blue_200';
7
+ import { chart_color_blue_400 } from '@patternfly/react-tokens/dist/js/chart_color_blue_400';
8
+ import { chart_color_red_orange_200 } from '@patternfly/react-tokens/dist/js/chart_color_red_orange_200';
9
+ import { getResizeObserver, getDomain, getLegendData, isSeriesHidden, isDataAvailable, initHiddenSeries } from './utils/chart-utils.esm.js';
10
+ import messages from './i18n/messages.esm.js';
11
+ import { unitsLookupKey } from './utils/format.esm.js';
12
+ import { getDateRangeString } from './utils/chart-datum.esm.js';
13
+
14
+ const useOptimizationsBreakdownChartStyles = makeStyles(() => ({
15
+ chartOverride: {
16
+ "& > div > div > svg": {
17
+ overflow: "visible"
18
+ }
19
+ }
20
+ }));
21
+ const chartStyles = {
22
+ limit: {
23
+ fill: "none"
24
+ },
25
+ limitColorScale: [chart_color_red_orange_200.value],
26
+ request: {
27
+ fill: "none"
28
+ },
29
+ requestColorScale: [chart_color_blue_400.value],
30
+ usageColorScale: [chart_color_blue_100.value, chart_color_blue_200.value]
31
+ };
32
+ const OptimizationsBreakdownChart = ({ baseHeight, name, limitData, padding, requestData, usageData }) => {
33
+ const [containerRef] = useState(React.createRef());
34
+ const [cursorVoronoiContainer, setCursorVoronoiContainer] = useState();
35
+ const [extraHeight, setExtraHeight] = useState(0);
36
+ const [hiddenSeries, setHiddenSeries] = useState(/* @__PURE__ */ new Set());
37
+ const [series, setSeries] = useState();
38
+ const [width, setWidth] = useState(0);
39
+ const intl = useIntl();
40
+ const classes = useOptimizationsBreakdownChartStyles();
41
+ const cloneContainer = () => {
42
+ const legendData = getLegendData(series, hiddenSeries, true);
43
+ legendData?.push(
44
+ {
45
+ childName: "usage",
46
+ name: "",
47
+ symbol: {
48
+ fill: "none"
49
+ }
50
+ },
51
+ {
52
+ childName: "usage",
53
+ name: "",
54
+ symbol: {
55
+ fill: "none"
56
+ }
57
+ }
58
+ );
59
+ return cursorVoronoiContainer ? React.cloneElement(cursorVoronoiContainer, {
60
+ disable: !isDataAvailable(series, hiddenSeries),
61
+ labelComponent: /* @__PURE__ */ React.createElement(
62
+ ChartLegendTooltip,
63
+ {
64
+ legendData,
65
+ title: (datum) => `${datum.x}`
66
+ }
67
+ )
68
+ }) : void 0;
69
+ };
70
+ const getLimitChart = () => {
71
+ return series?.map((serie, index) => {
72
+ if (serie.childName === "limit") {
73
+ return /* @__PURE__ */ React.createElement(
74
+ ChartArea,
75
+ {
76
+ data: !hiddenSeries.has(index) ? serie.data : [{ y: null }],
77
+ interpolation: "monotoneX",
78
+ key: serie.childName,
79
+ name: serie.childName,
80
+ style: serie.style
81
+ }
82
+ );
83
+ }
84
+ return null;
85
+ });
86
+ };
87
+ const getRequestChart = () => {
88
+ return series?.map((serie, index) => {
89
+ if (serie.childName === "request") {
90
+ return /* @__PURE__ */ React.createElement(
91
+ ChartArea,
92
+ {
93
+ data: !hiddenSeries.has(index) ? serie.data : [{ y: null }],
94
+ interpolation: "monotoneX",
95
+ key: serie.childName,
96
+ name: serie.childName,
97
+ style: serie.style
98
+ }
99
+ );
100
+ }
101
+ return null;
102
+ });
103
+ };
104
+ const getScatterChart = () => {
105
+ return series?.map((serie, index) => {
106
+ if (serie.childName === "scatter") {
107
+ return /* @__PURE__ */ React.createElement(
108
+ ChartScatter,
109
+ {
110
+ data: !hiddenSeries.has(index - 1) ? serie.data : [{ y: null }],
111
+ key: serie.childName,
112
+ name: serie.childName,
113
+ style: serie.style
114
+ }
115
+ );
116
+ }
117
+ return null;
118
+ });
119
+ };
120
+ const getUsageChart = () => {
121
+ return series?.map((serie, index) => {
122
+ if (serie.childName === "usage") {
123
+ return /* @__PURE__ */ React.createElement(
124
+ ChartBoxPlot,
125
+ {
126
+ boxWidth: width < 475 ? 15 : void 0,
127
+ data: !hiddenSeries.has(index) ? serie.data : [{ y: [null] }],
128
+ key: serie.childName,
129
+ name: serie.childName,
130
+ style: serie.style
131
+ }
132
+ );
133
+ }
134
+ return null;
135
+ });
136
+ };
137
+ const getChartNames = () => {
138
+ const result = [];
139
+ if (series) {
140
+ series.forEach((serie) => {
141
+ if (serie.childName === "usage") {
142
+ result.push([serie.childName, "scatter"]);
143
+ } else if (serie.childName !== "scatter") {
144
+ result.push(serie.childName);
145
+ }
146
+ });
147
+ }
148
+ return result;
149
+ };
150
+ const getPadding = useCallback(() => {
151
+ return padding ? padding : {
152
+ bottom: 75 + extraHeight,
153
+ // Maintain chart aspect ratio
154
+ left: 50,
155
+ right: 50,
156
+ top: 10
157
+ };
158
+ }, [extraHeight, padding]);
159
+ const handleOnLegendClick = (index) => {
160
+ const newHiddenSeries = initHiddenSeries(hiddenSeries, index);
161
+ setHiddenSeries(newHiddenSeries);
162
+ };
163
+ const getCursorVoronoiContainer = useCallback(() => {
164
+ const CursorVoronoiContainer = createContainer("voronoi", "cursor");
165
+ const labelFormatter = (datum) => {
166
+ const formatValue = (val) => val !== void 0 ? val : "";
167
+ if (datum.childName === "scatter") {
168
+ return null;
169
+ } else if (datum.childName === "usage" && (datum._min !== void 0 || datum._max !== void 0 || datum._median !== void 0 || datum._q1 !== void 0 || datum._q3 !== void 0 || datum.yVal !== null)) {
170
+ return intl.formatMessage(messages.chartUsageTooltip, {
171
+ br: "\n",
172
+ min: formatValue(datum._min !== void 0 ? datum._min : datum.yVal),
173
+ max: formatValue(datum._max !== void 0 ? datum._max : datum.yVal),
174
+ median: formatValue(
175
+ datum._median !== void 0 ? datum._median : datum.yVal
176
+ ),
177
+ q1: formatValue(datum._q1 !== void 0 ? datum._q1 : datum.yVal),
178
+ q3: formatValue(datum._q3 !== void 0 ? datum._q3 : datum.yVal),
179
+ units: intl.formatMessage(messages.units, {
180
+ units: unitsLookupKey(datum.units)
181
+ })
182
+ });
183
+ }
184
+ const yVal = Array.isArray(datum.y) ? datum.y[0] : datum.y;
185
+ let units = datum.units;
186
+ if ((datum.childName === "limit" || datum.childName === "request") && datum.units === "") {
187
+ units = unitsLookupKey("cores");
188
+ }
189
+ return yVal !== null ? intl.formatMessage(messages.valueUnits, {
190
+ value: yVal,
191
+ units: intl.formatMessage(messages.units, {
192
+ units: unitsLookupKey(units)
193
+ })
194
+ }) : intl.formatMessage(messages.chartNoData);
195
+ };
196
+ return /* @__PURE__ */ React.createElement(
197
+ CursorVoronoiContainer,
198
+ {
199
+ cursorDimension: "x",
200
+ labels: ({ datum }) => labelFormatter(datum),
201
+ mouseFollowTooltips: true,
202
+ voronoiDimension: "x",
203
+ voronoiPadding: getPadding()
204
+ }
205
+ );
206
+ }, [getPadding, intl]);
207
+ const getEvents = () => {
208
+ const result = getInteractiveLegendEvents({
209
+ chartNames: getChartNames(),
210
+ isHidden: (index) => isSeriesHidden(hiddenSeries, index),
211
+ legendName: `${name}-legend`,
212
+ onLegendClick: (props) => handleOnLegendClick(props.index)
213
+ });
214
+ return result;
215
+ };
216
+ const getHeight = () => {
217
+ return baseHeight + extraHeight;
218
+ };
219
+ const getLegend = () => {
220
+ return /* @__PURE__ */ React.createElement(
221
+ ChartLegend,
222
+ {
223
+ data: getLegendData(series, hiddenSeries),
224
+ gutter: 20,
225
+ name: `${name}-legend`,
226
+ y: 320
227
+ }
228
+ );
229
+ };
230
+ const handleLegendAllowWrap = (value) => {
231
+ if (value !== extraHeight) {
232
+ setExtraHeight(value);
233
+ }
234
+ };
235
+ const handleOnResize = useCallback(() => {
236
+ const { clientWidth = 0 } = containerRef.current || {};
237
+ if (clientWidth !== width) {
238
+ setWidth(clientWidth);
239
+ }
240
+ }, [containerRef, width]);
241
+ const initDatum = useCallback(() => {
242
+ const newSeries = [];
243
+ if (requestData && requestData.length) {
244
+ newSeries.push({
245
+ childName: "request",
246
+ data: requestData,
247
+ legendItem: {
248
+ name: getDateRangeString(
249
+ requestData,
250
+ messages.recommendedRequest,
251
+ true
252
+ ),
253
+ symbol: {
254
+ fill: chartStyles.requestColorScale[0],
255
+ type: "square"
256
+ },
257
+ tooltip: intl.formatMessage(messages.request)
258
+ },
259
+ style: {
260
+ data: {
261
+ ...chartStyles.request,
262
+ stroke: chartStyles.requestColorScale[0]
263
+ }
264
+ }
265
+ });
266
+ }
267
+ if (limitData && limitData.length) {
268
+ newSeries.push({
269
+ childName: "limit",
270
+ data: limitData,
271
+ legendItem: {
272
+ name: getDateRangeString(limitData, messages.recommendedLimit, true),
273
+ symbol: {
274
+ fill: chartStyles.limitColorScale[0],
275
+ type: "square"
276
+ },
277
+ tooltip: intl.formatMessage(messages.limit)
278
+ },
279
+ style: {
280
+ data: {
281
+ ...chartStyles.limit,
282
+ stroke: chartStyles.limitColorScale[0]
283
+ }
284
+ }
285
+ });
286
+ }
287
+ if (usageData && usageData.length) {
288
+ const boxPlotData = [];
289
+ usageData.map((datum) => {
290
+ if (datum.y.every((val, _i, arr) => val === arr[0])) {
291
+ boxPlotData.push({
292
+ ...datum,
293
+ yVal: datum.y[0],
294
+ y: [null]
295
+ });
296
+ } else {
297
+ boxPlotData.push(datum);
298
+ }
299
+ });
300
+ newSeries.push({
301
+ childName: "usage",
302
+ data: boxPlotData,
303
+ legendItem: {
304
+ name: getDateRangeString(usageData, messages.actualUsage),
305
+ symbol: {
306
+ fill: chartStyles.usageColorScale[1],
307
+ type: "square"
308
+ },
309
+ tooltip: intl.formatMessage(messages.usage)
310
+ },
311
+ style: {
312
+ median: {
313
+ stroke: chartStyles.usageColorScale[0]
314
+ },
315
+ q1: {
316
+ fill: chartStyles.usageColorScale[1]
317
+ },
318
+ q3: {
319
+ fill: chartStyles.usageColorScale[1]
320
+ }
321
+ }
322
+ });
323
+ const scatterData = [];
324
+ usageData.map((datum) => {
325
+ if (datum.y.every((val, _i, arr) => val === arr[0])) {
326
+ scatterData.push({
327
+ ...datum,
328
+ y: datum.y[0]
329
+ });
330
+ } else {
331
+ scatterData.push({
332
+ ...datum,
333
+ y: null
334
+ });
335
+ }
336
+ });
337
+ newSeries.push({
338
+ childName: "scatter",
339
+ data: scatterData,
340
+ style: {
341
+ data: { fill: chartStyles.usageColorScale[1] }
342
+ }
343
+ });
344
+ }
345
+ setSeries(newSeries);
346
+ setCursorVoronoiContainer(getCursorVoronoiContainer());
347
+ setHiddenSeries(/* @__PURE__ */ new Set());
348
+ }, [getCursorVoronoiContainer, intl, limitData, requestData, usageData]);
349
+ useMemo(() => {
350
+ initDatum();
351
+ }, [initDatum]);
352
+ useEffect(() => {
353
+ const unobserve = getResizeObserver(containerRef.current, handleOnResize);
354
+ return () => {
355
+ if (unobserve) {
356
+ unobserve();
357
+ }
358
+ };
359
+ }, [containerRef, handleOnResize]);
360
+ const chartHeight = getHeight();
361
+ return /* @__PURE__ */ React.createElement("div", { className: classes.chartOverride, ref: containerRef }, /* @__PURE__ */ React.createElement("div", { style: { height: chartHeight } }, /* @__PURE__ */ React.createElement(
362
+ Chart,
363
+ {
364
+ key: `chart-${name}`,
365
+ containerComponent: cloneContainer(),
366
+ domain: getDomain(series, hiddenSeries, 1),
367
+ domainPadding: { x: [30, 30] },
368
+ events: getEvents(),
369
+ height: chartHeight,
370
+ legendAllowWrap: handleLegendAllowWrap,
371
+ legendComponent: getLegend(),
372
+ legendPosition: "bottom",
373
+ name,
374
+ padding: getPadding(),
375
+ width,
376
+ themeColor: ChartThemeColor.default
377
+ },
378
+ /* @__PURE__ */ React.createElement(ChartAxis, { fixLabelOverlap: true }),
379
+ /* @__PURE__ */ React.createElement(ChartAxis, { dependentAxis: true, showGrid: true }),
380
+ getRequestChart(),
381
+ getLimitChart(),
382
+ getScatterChart(),
383
+ getUsageChart()
384
+ )));
385
+ };
386
+
387
+ export { OptimizationsBreakdownChart, chartStyles };
388
+ //# sourceMappingURL=OptimizationsBreakdownChart.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OptimizationsBreakdownChart.esm.js","sources":["../../../../../../../../../../../../../src/pages/optimizations-breakdown/components/optimization-engine-tab/components/chart-info-card/components/intl-breakdown-chart/components/optimizations-breakdown-chart/components/optimizations-breakdown-chart/OptimizationsBreakdownChart.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React, { useCallback, useEffect, useMemo, useState } from 'react';\nimport { useIntl } from 'react-intl';\nimport { makeStyles } from '@material-ui/core/styles';\nimport {\n Chart,\n ChartArea,\n ChartAxis,\n ChartBoxPlot,\n ChartLegend,\n ChartLegendTooltip,\n ChartScatter,\n createContainer,\n getInteractiveLegendEvents,\n ChartThemeColor,\n} from '@patternfly/react-charts/victory';\nimport { chart_color_blue_100 } from '@patternfly/react-tokens/dist/js/chart_color_blue_100';\nimport { chart_color_blue_200 } from '@patternfly/react-tokens/dist/js/chart_color_blue_200';\nimport { chart_color_blue_400 } from '@patternfly/react-tokens/dist/js/chart_color_blue_400';\nimport { chart_color_red_orange_200 } from '@patternfly/react-tokens/dist/js/chart_color_red_orange_200';\nimport { ChartSeries } from './types/ChartSeries';\nimport {\n getDomain,\n getLegendData,\n getResizeObserver,\n initHiddenSeries,\n isDataAvailable,\n isSeriesHidden,\n} from './utils/chart-utils';\nimport messages from './i18n/messages';\nimport { unitsLookupKey } from './utils/format';\nimport { getDateRangeString } from './utils/chart-datum';\n\nconst useOptimizationsBreakdownChartStyles = makeStyles(() => ({\n chartOverride: {\n '& > div > div > svg': {\n overflow: 'visible',\n },\n },\n}));\n\nexport const chartStyles = {\n limit: {\n fill: 'none',\n },\n limitColorScale: [chart_color_red_orange_200.value],\n request: {\n fill: 'none',\n },\n requestColorScale: [chart_color_blue_400.value],\n usageColorScale: [chart_color_blue_100.value, chart_color_blue_200.value],\n};\n\ninterface OptimizationsBreakdownChartOwnProps {\n baseHeight: number;\n limitData?: any;\n name?: string;\n padding?: any;\n requestData?: any;\n usageData?: any;\n}\n\ntype OptimizationsBreakdownChartProps = OptimizationsBreakdownChartOwnProps;\n\nconst OptimizationsBreakdownChart: React.FC<\n OptimizationsBreakdownChartProps\n> = ({ baseHeight, name, limitData, padding, requestData, usageData }) => {\n const [containerRef] = useState(React.createRef<HTMLDivElement>());\n const [cursorVoronoiContainer, setCursorVoronoiContainer] = useState<any>();\n const [extraHeight, setExtraHeight] = useState(0);\n const [hiddenSeries, setHiddenSeries] = useState(new Set<number>());\n const [series, setSeries] = useState<ChartSeries[]>();\n const [width, setWidth] = useState(0);\n\n const intl = useIntl();\n const classes = useOptimizationsBreakdownChartStyles();\n\n // Clone original container. See https://issues.redhat.com/browse/COST-762\n const cloneContainer = () => {\n const legendData = getLegendData(series, hiddenSeries, true);\n // Force extra space for line wrapping\n legendData?.push(\n {\n childName: 'usage',\n name: '',\n symbol: {\n fill: 'none',\n },\n },\n {\n childName: 'usage',\n name: '',\n symbol: {\n fill: 'none',\n },\n },\n );\n return cursorVoronoiContainer\n ? React.cloneElement(cursorVoronoiContainer, {\n disable: !isDataAvailable(series, hiddenSeries),\n labelComponent: (\n <ChartLegendTooltip\n legendData={legendData}\n title={datum => `${datum.x}`}\n />\n ),\n } as any)\n : undefined;\n };\n\n const getLimitChart = () => {\n return series?.map((serie, index) => {\n if (serie.childName === 'limit') {\n return (\n <ChartArea\n data={!hiddenSeries.has(index) ? serie.data : [{ y: null }]}\n interpolation=\"monotoneX\"\n key={serie.childName}\n name={serie.childName}\n style={serie.style}\n />\n );\n }\n return null;\n });\n };\n\n const getRequestChart = () => {\n return series?.map((serie, index) => {\n if (serie.childName === 'request') {\n return (\n <ChartArea\n data={!hiddenSeries.has(index) ? serie.data : [{ y: null }]}\n interpolation=\"monotoneX\"\n key={serie.childName}\n name={serie.childName}\n style={serie.style}\n />\n );\n }\n return null;\n });\n };\n\n const getScatterChart = () => {\n return series?.map((serie, index) => {\n if (serie.childName === 'scatter') {\n return (\n <ChartScatter\n data={!hiddenSeries.has(index - 1) ? serie.data : [{ y: null }]}\n key={serie.childName}\n name={serie.childName}\n style={serie.style}\n />\n );\n }\n return null;\n });\n };\n\n const getUsageChart = () => {\n return series?.map((serie, index) => {\n if (serie.childName === 'usage') {\n return (\n <ChartBoxPlot\n boxWidth={width < 475 ? 15 : undefined}\n data={!hiddenSeries.has(index) ? serie.data : [{ y: [null] }]}\n key={serie.childName}\n name={serie.childName}\n style={serie.style}\n />\n );\n }\n return null;\n });\n };\n\n // Returns groups of chart names associated with each data series\n const getChartNames = () => {\n const result: (string | string[] | undefined)[] = [];\n\n if (series) {\n series.forEach(serie => {\n // Each group of chart names are hidden / shown together\n if (serie.childName === 'usage') {\n result.push([serie.childName, 'scatter']);\n } else if (serie.childName !== 'scatter') {\n result.push(serie.childName);\n }\n });\n }\n return result as any;\n };\n\n const getPadding = useCallback(() => {\n return padding\n ? padding\n : {\n bottom: 75 + extraHeight, // Maintain chart aspect ratio\n left: 50,\n right: 50,\n top: 10,\n };\n }, [extraHeight, padding]);\n\n // Hide each data series individually\n const handleOnLegendClick = (index: number) => {\n const newHiddenSeries = initHiddenSeries(hiddenSeries, index);\n setHiddenSeries(newHiddenSeries);\n };\n\n // Returns CursorVoronoiContainer component\n const getCursorVoronoiContainer = useCallback(() => {\n // Note: Container order is important\n const CursorVoronoiContainer: any = createContainer('voronoi', 'cursor');\n\n const labelFormatter = (datum: {\n childName: string;\n _min: undefined;\n _max: undefined;\n _median: undefined;\n _q1: undefined;\n _q3: undefined;\n yVal: null;\n units: string;\n y: any[];\n }) => {\n const formatValue = (val: undefined | null) =>\n val !== undefined ? val : '';\n if (datum.childName === 'scatter') {\n return null;\n } else if (\n datum.childName === 'usage' &&\n (datum._min !== undefined ||\n datum._max !== undefined ||\n datum._median !== undefined ||\n datum._q1 !== undefined ||\n datum._q3 !== undefined ||\n datum.yVal !== null)\n ) {\n return intl.formatMessage(messages.chartUsageTooltip, {\n br: '\\n',\n min: formatValue(datum._min !== undefined ? datum._min : datum.yVal),\n max: formatValue(datum._max !== undefined ? datum._max : datum.yVal),\n median: formatValue(\n datum._median !== undefined ? datum._median : datum.yVal,\n ),\n q1: formatValue(datum._q1 !== undefined ? datum._q1 : datum.yVal),\n q3: formatValue(datum._q3 !== undefined ? datum._q3 : datum.yVal),\n units: intl.formatMessage(messages.units, {\n units: unitsLookupKey(datum.units),\n }),\n });\n }\n\n // With box plot, datum.y will be an array\n const yVal = Array.isArray(datum.y) ? datum.y[0] : datum.y;\n let units = datum.units;\n\n /**\n * The recommendations API intentionally omits CPU request and limit units when \"cores\".\n *\n * The yaml format for the resource units needs to adhere to the Kubernetes standard that is outlined here\n * https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n *\n * Example. \"45 millicores\" is represented as \"45m\", 64 MiB is represented as \"64Mi\",\n * 2.3 cores is represented as \"2.3\" (Note cores is not specified)\n */\n if (\n (datum.childName === 'limit' || datum.childName === 'request') &&\n datum.units === ''\n ) {\n units = unitsLookupKey('cores');\n }\n return yVal !== null\n ? intl.formatMessage(messages.valueUnits, {\n value: yVal,\n units: intl.formatMessage(messages.units, {\n units: unitsLookupKey(units),\n }),\n })\n : intl.formatMessage(messages.chartNoData);\n };\n\n return (\n <CursorVoronoiContainer\n cursorDimension=\"x\"\n labels={({ datum }: any) => labelFormatter(datum)}\n mouseFollowTooltips\n voronoiDimension=\"x\"\n voronoiPadding={getPadding()}\n />\n );\n }, [getPadding, intl]);\n\n // Returns onMouseOver, onMouseOut, and onClick events for the interactive legend\n const getEvents = () => {\n const result = getInteractiveLegendEvents({\n chartNames: getChartNames(),\n isHidden: index => isSeriesHidden(hiddenSeries, index),\n legendName: `${name}-legend`,\n onLegendClick: props => handleOnLegendClick(props.index),\n });\n return result;\n };\n\n const getHeight = () => {\n return baseHeight + extraHeight;\n };\n\n const getLegend = () => {\n return (\n <ChartLegend\n data={getLegendData(series, hiddenSeries)}\n gutter={20}\n name={`${name}-legend`}\n y={320}\n />\n );\n };\n\n const handleLegendAllowWrap = (value: number) => {\n if (value !== extraHeight) {\n setExtraHeight(value);\n }\n };\n\n const handleOnResize = useCallback(() => {\n const { clientWidth = 0 } = containerRef.current || {};\n\n if (clientWidth !== width) {\n setWidth(clientWidth);\n }\n }, [containerRef, width]);\n\n const initDatum = useCallback(() => {\n // Show all legends, regardless of data size\n\n const newSeries: ChartSeries[] = [];\n if (requestData && requestData.length) {\n newSeries.push({\n childName: 'request',\n data: requestData,\n legendItem: {\n name: getDateRangeString(\n requestData,\n messages.recommendedRequest,\n true,\n ),\n symbol: {\n fill: chartStyles.requestColorScale[0],\n type: 'square',\n },\n tooltip: intl.formatMessage(messages.request),\n },\n style: {\n data: {\n ...chartStyles.request,\n stroke: chartStyles.requestColorScale[0],\n },\n },\n });\n }\n if (limitData && limitData.length) {\n newSeries.push({\n childName: 'limit',\n data: limitData,\n legendItem: {\n name: getDateRangeString(limitData, messages.recommendedLimit, true),\n symbol: {\n fill: chartStyles.limitColorScale[0],\n type: 'square',\n },\n tooltip: intl.formatMessage(messages.limit),\n },\n style: {\n data: {\n ...chartStyles.limit,\n stroke: chartStyles.limitColorScale[0],\n },\n },\n });\n }\n if (usageData && usageData.length) {\n const boxPlotData: any[] = [];\n usageData.map((datum: any) => {\n if (datum.y.every((val: any, _i: any, arr: any[]) => val === arr[0])) {\n boxPlotData.push({\n ...datum,\n yVal: datum.y[0],\n y: [null],\n });\n } else {\n boxPlotData.push(datum);\n }\n });\n newSeries.push({\n childName: 'usage',\n data: boxPlotData as any,\n legendItem: {\n name: getDateRangeString(usageData, messages.actualUsage),\n symbol: {\n fill: chartStyles.usageColorScale[1],\n type: 'square',\n },\n tooltip: intl.formatMessage(messages.usage),\n },\n style: {\n median: {\n stroke: chartStyles.usageColorScale[0],\n },\n q1: {\n fill: chartStyles.usageColorScale[1],\n },\n q3: {\n fill: chartStyles.usageColorScale[1],\n },\n } as any,\n });\n\n // Show dots in place of box plot when all values are equal\n const scatterData: any[] = [];\n usageData.map((datum: any) => {\n if (datum.y.every((val: any, _i: any, arr: any[]) => val === arr[0])) {\n scatterData.push({\n ...datum,\n y: datum.y[0],\n });\n } else {\n scatterData.push({\n ...datum,\n y: null,\n });\n }\n });\n newSeries.push({\n childName: 'scatter',\n data: scatterData as any,\n style: {\n data: { fill: chartStyles.usageColorScale[1] },\n } as any,\n });\n }\n setSeries(newSeries);\n setCursorVoronoiContainer(getCursorVoronoiContainer());\n setHiddenSeries(new Set());\n }, [getCursorVoronoiContainer, intl, limitData, requestData, usageData]);\n\n useMemo(() => {\n initDatum();\n }, [initDatum]);\n\n useEffect(() => {\n const unobserve = getResizeObserver(containerRef.current, handleOnResize);\n return () => {\n if (unobserve) {\n unobserve();\n }\n };\n }, [containerRef, handleOnResize]);\n\n const chartHeight = getHeight();\n\n return (\n <div className={classes.chartOverride} ref={containerRef}>\n <div style={{ height: chartHeight }}>\n <Chart\n key={`chart-${name}`}\n containerComponent={cloneContainer()}\n domain={getDomain(series, hiddenSeries, 1)}\n domainPadding={{ x: [30, 30] }}\n events={getEvents()}\n height={chartHeight}\n legendAllowWrap={handleLegendAllowWrap}\n legendComponent={getLegend()}\n legendPosition=\"bottom\"\n name={name}\n padding={getPadding()}\n width={width}\n // PatternFly will handle theming automatically when pf-v6-theme-dark is applied\n themeColor={ChartThemeColor.default}\n >\n <ChartAxis fixLabelOverlap />\n <ChartAxis dependentAxis showGrid />\n {getRequestChart()}\n {getLimitChart()}\n {getScatterChart()}\n {getUsageChart()}\n </Chart>\n </div>\n </div>\n );\n};\n\nexport { OptimizationsBreakdownChart };\n"],"names":[],"mappings":"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"}