From 98bc4c3e9458aea98890b770493f14327a7bc7c4 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Thu, 15 Sep 2022 22:52:00 +0200 Subject: refactor(web/ui): Use PatternFly Charts for plots This change updates the OpenDC web interface to use the PatternFly Charts package to render the results of a portfolio. Previously, we used Recharts, but this package does not support SSR, whereas the PatternFly Charts package matches our design framework. --- opendc-web/opendc-web-ui/package-lock.json | 1007 +++++++++++++++----- opendc-web/opendc-web-ui/package.json | 6 +- .../src/components/portfolios/PortfolioResults.js | 132 +-- .../projects/[project]/portfolios/[portfolio].js | 3 +- 4 files changed, 826 insertions(+), 322 deletions(-) (limited to 'opendc-web') diff --git a/opendc-web/opendc-web-ui/package-lock.json b/opendc-web/opendc-web-ui/package-lock.json index ccaf4dda..a38802de 100644 --- a/opendc-web/opendc-web-ui/package-lock.json +++ b/opendc-web/opendc-web-ui/package-lock.json @@ -13,12 +13,12 @@ "@fortawesome/fontawesome-svg-core": "^6.2.0", "@fortawesome/free-solid-svg-icons": "^6.2.0", "@fortawesome/react-fontawesome": "^0.2.0", + "@patternfly/react-charts": "^6.88.7", "@patternfly/react-core": "^4.235.7", "@patternfly/react-icons": "^4.86.7", "@patternfly/react-table": "^4.104.7", "@sentry/react": "^6.19.7", "@sentry/tracing": "^6.19.7", - "approximate-number": "^2.1.0", "clsx": "^1.2.1", "immer": "^9.0.15", "konva": "^8.3.12", @@ -34,7 +34,6 @@ "react-konva": "^17.0.2-6", "react-query": "^3.39.2", "react-redux": "^8.0.2", - "recharts": "^2.1.14", "redux": "^4.2.0", "redux-logger": "^3.0.6", "redux-saga": "^1.2.1", @@ -42,7 +41,8 @@ "sass": "^1.54.9", "svgsaver": "^0.9.0", "use-resize-observer": "^9.0.2", - "uuid": "^8.3.2" + "uuid": "^8.3.2", + "victory-errorbar": "^36.6.7" }, "devDependencies": { "eslint": "^8.23.1", @@ -481,6 +481,43 @@ "node": ">= 8" } }, + "node_modules/@patternfly/react-charts": { + "version": "6.88.7", + "resolved": "https://registry.npmjs.org/@patternfly/react-charts/-/react-charts-6.88.7.tgz", + "integrity": "sha512-1SGDHfTmjH3c54ym1i1d1SH1DGArn96Fwkv1woOTpRhNgBoz6TkoDJGHfpX6UUyun1uqDMUdNP8tOnb9SITuvQ==", + "dependencies": { + "@patternfly/react-styles": "^4.85.7", + "@patternfly/react-tokens": "^4.87.7", + "hoist-non-react-statics": "^3.3.0", + "lodash": "^4.17.19", + "tslib": "^2.0.0", + "victory-area": "^36.2.1", + "victory-axis": "^36.2.1", + "victory-bar": "^36.2.1", + "victory-chart": "^36.2.1", + "victory-core": "^36.2.1", + "victory-create-container": "^36.2.1", + "victory-cursor-container": "^36.2.1", + "victory-group": "^36.2.1", + "victory-legend": "^36.2.1", + "victory-line": "^36.2.1", + "victory-pie": "^36.2.1", + "victory-scatter": "^36.2.1", + "victory-stack": "^36.2.1", + "victory-tooltip": "^36.2.1", + "victory-voronoi-container": "^36.2.1", + "victory-zoom-container": "^36.2.1" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0", + "react-dom": "^16.8.0 || ^17.0.0" + } + }, + "node_modules/@patternfly/react-charts/node_modules/tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + }, "node_modules/@patternfly/react-core": { "version": "4.235.7", "resolved": "https://registry.npmjs.org/@patternfly/react-core/-/react-core-4.235.7.tgz", @@ -726,11 +763,21 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" }, + "node_modules/@types/d3-array": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.0.3.tgz", + "integrity": "sha512-Reoy+pKnvsksN0lQUlcH6dOGjRZ/3WRwXR//m+/8lt1BXeI4xyaUZoqULNjyXXRuh0Mj4LNpkCvhUpQlY3X5xQ==" + }, "node_modules/@types/d3-color": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.0.tgz", "integrity": "sha512-HKuicPHJuvPgCD+np6Se9MQvS6OCbJmOjGvylzMJRlDwUXjKTTXs6Pwgk79O09Vj/ho3u1ofXnhFOaEWWPrlwA==" }, + "node_modules/@types/d3-ease": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.0.tgz", + "integrity": "sha512-aMo4eaAOijJjA6uU+GIeW018dvy9+oH5Y2VPPzjjfxevvGQ/oRDs+tfYC9b50Q4BygRR8yE2QCLsrT0WtAVseA==" + }, "node_modules/@types/d3-interpolate": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.1.tgz", @@ -765,6 +812,11 @@ "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.0.tgz", "integrity": "sha512-sZLCdHvBUcNby1cB6Fd3ZBrABbjz3v1Vm90nysCQ6Vt7vd6e/h9Lt7SiJUoEX0l4Dzc7P5llKyhqSi1ycSf1Hg==" }, + "node_modules/@types/d3-timer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.0.tgz", + "integrity": "sha512-HNB/9GHqu7Fo8AQiugyJbv6ZxYz58wef0esl4Mv828w1ZKpAshw/uFWVDUcIB9KKFeFKoxS3cHY07FFgtTRZ1g==" + }, "node_modules/@types/hoist-non-react-statics": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", @@ -994,12 +1046,6 @@ "node": ">= 8" } }, - "node_modules/approximate-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/approximate-number/-/approximate-number-2.1.0.tgz", - "integrity": "sha512-EioK6nto/hEnwaJ7d/TG1WOZ9o0zTyIFVP4Lk7zzR/3I4O7ivkBNo7EvLC2Xh2j2HD/cb9sUqXHdexfGXCXYDA==", - "license": "MIT" - }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -1279,11 +1325,6 @@ "fsevents": "~2.3.2" } }, - "node_modules/classnames": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", - "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" - }, "node_modules/clsx": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", @@ -1373,12 +1414,6 @@ "node": ">= 8" } }, - "node_modules/css-unit-converter": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/css-unit-converter/-/css-unit-converter-1.1.2.tgz", - "integrity": "sha512-IiJwMC8rdZE0+xiEZHeru6YoONC4rfPMqGm2W85jMIbkFvv5nFTwJVFHam2eFrN6txmoUYFAFXiv8ICVeTO0MA==", - "license": "MIT" - }, "node_modules/csstype": { "version": "3.0.11", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.11.tgz", @@ -1403,6 +1438,14 @@ "node": ">=12" } }, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "engines": { + "node": ">=12" + } + }, "node_modules/d3-format": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", @@ -1478,6 +1521,14 @@ "node": ">=12" } }, + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "engines": { + "node": ">=12" + } + }, "node_modules/damerau-levenshtein": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", @@ -1508,12 +1559,6 @@ "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.0.tgz", "integrity": "sha512-Nv6ENEzyPQ6AItkGwLE2PGKinZZ9g59vSh2BeH6NqPu0OTKZ5ruJsVqh/orbAnqXc9pBbgXAIrc2EyaCj8NpGg==" }, - "node_modules/decimal.js-light": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz", - "integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==", - "license": "MIT" - }, "node_modules/deep-diff": { "version": "0.3.8", "resolved": "https://registry.npmjs.org/deep-diff/-/deep-diff-0.3.8.tgz", @@ -1543,6 +1588,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/delaunator": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-4.0.1.tgz", + "integrity": "sha512-WNPWi1IRKZfCt/qIDMfERkDp93+iZEmOxN2yy4Jg+Xhv8SLk2UTqqbe1sfiipn0and9QrE914/ihdx82Y/Giag==" + }, + "node_modules/delaunay-find": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/delaunay-find/-/delaunay-find-0.0.6.tgz", + "integrity": "sha512-1+almjfrnR7ZamBk0q3Nhg6lqSe6Le4vL0WJDSMx4IDbQwTpUTXPjxC00lqLBT8MYsJpPCbI16sIkw9cPsbi7Q==", + "dependencies": { + "delaunator": "^4.0.0" + } + }, "node_modules/detect-node": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", @@ -1573,14 +1631,6 @@ "node": ">=0.10.0" } }, - "node_modules/dom-helpers": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.4.0.tgz", - "integrity": "sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==", - "dependencies": { - "@babel/runtime": "^7.1.2" - } - }, "node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", @@ -2162,23 +2212,12 @@ "node": ">=0.10.0" } }, - "node_modules/eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", - "license": "MIT" - }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, - "node_modules/fast-equals": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-2.0.4.tgz", - "integrity": "sha512-caj/ZmjHljPrZtbzJ3kfH5ia/k4mTJe/qSiXAGzxZWRZgsgDV0cvNaQULqUX8t0/JVlzzEdYOwCN5DmzTxoD4w==" - }, "node_modules/fast-glob": { "version": "3.2.11", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", @@ -2928,6 +2967,11 @@ "dev": true, "license": "MIT" }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" + }, "node_modules/json5": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", @@ -3518,12 +3562,6 @@ "node": "^10 || ^12 || >=14" } }, - "node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "license": "MIT" - }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -3649,6 +3687,11 @@ "react": ">=0.14.0" } }, + "node_modules/react-fast-compare": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz", + "integrity": "sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==" + }, "node_modules/react-hotkeys-hook": { "version": "3.4.7", "resolved": "https://registry.npmjs.org/react-hotkeys-hook/-/react-hotkeys-hook-3.4.7.tgz", @@ -3696,11 +3739,6 @@ "react-dom": ">=16.8.0" } }, - "node_modules/react-lifecycles-compat": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", - "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" - }, "node_modules/react-query": { "version": "3.39.2", "resolved": "https://registry.npmjs.org/react-query/-/react-query-3.39.2.tgz", @@ -3785,47 +3823,6 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.1.0.tgz", "integrity": "sha512-Fl7FuabXsJnV5Q1qIOQwx/sagGF18kogb4gpfcG4gjLBWO0WDiiz1ko/ExayuxE7InyQkBLkxRFG5oxY6Uu3Kg==" }, - "node_modules/react-resize-detector": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/react-resize-detector/-/react-resize-detector-7.1.2.tgz", - "integrity": "sha512-zXnPJ2m8+6oq9Nn8zsep/orts9vQv3elrpA+R8XTcW7DVVUJ9vwDwMXaBtykAYjMnkCIaOoK9vObyR7ZgFNlOw==", - "dependencies": { - "lodash": "^4.17.21" - }, - "peerDependencies": { - "react": "^16.0.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/react-smooth": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-2.0.1.tgz", - "integrity": "sha512-Own9TA0GPPf3as4vSwFhDouVfXP15ie/wIHklhyKBH5AN6NFtdk0UpHBnonV11BtqDkAWlt40MOUc+5srmW7NA==", - "dependencies": { - "fast-equals": "^2.0.0", - "react-transition-group": "2.9.0" - }, - "peerDependencies": { - "prop-types": "^15.6.0", - "react": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/react-transition-group": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.9.0.tgz", - "integrity": "sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg==", - "dependencies": { - "dom-helpers": "^3.4.0", - "loose-envify": "^1.4.0", - "prop-types": "^15.6.2", - "react-lifecycles-compat": "^3.0.4" - }, - "peerDependencies": { - "react": ">=15.0.0", - "react-dom": ">=15.0.0" - } - }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -3837,54 +3834,6 @@ "node": ">=8.10.0" } }, - "node_modules/recharts": { - "version": "2.1.14", - "resolved": "https://registry.npmjs.org/recharts/-/recharts-2.1.14.tgz", - "integrity": "sha512-GDmDDPEmRhGb6O41OfJUKh/RFYh3QMtEdaNuXOnVtJN8wiifo41MvIHHzrjf7Vp7/yJYFsGaXnCElzM5H7SPmQ==", - "dependencies": { - "@types/d3-interpolate": "^3.0.1", - "@types/d3-scale": "^4.0.2", - "@types/d3-shape": "^3.1.0", - "classnames": "^2.2.5", - "d3-interpolate": "^3.0.1", - "d3-scale": "^4.0.2", - "d3-shape": "^3.1.0", - "eventemitter3": "^4.0.1", - "lodash": "^4.17.19", - "react-is": "^16.10.2", - "react-resize-detector": "^7.1.2", - "react-smooth": "^2.0.1", - "recharts-scale": "^0.4.4", - "reduce-css-calc": "^2.1.8" - }, - "engines": { - "node": ">=12" - }, - "peerDependencies": { - "prop-types": "^15.6.0", - "react": "^16.0.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/recharts-scale": { - "version": "0.4.5", - "resolved": "https://registry.npmjs.org/recharts-scale/-/recharts-scale-0.4.5.tgz", - "integrity": "sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w==", - "license": "MIT", - "dependencies": { - "decimal.js-light": "^2.4.1" - } - }, - "node_modules/reduce-css-calc": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-2.1.8.tgz", - "integrity": "sha512-8liAVezDmUcH+tdzoEGrhfbGcP7nOV4NkGE3a74+qqvE7nt9i4sKLGBuZNOnpI4WiGksiNPklZxva80061QiPg==", - "license": "MIT", - "dependencies": { - "css-unit-converter": "^1.1.1", - "postcss-value-parser": "^3.3.0" - } - }, "node_modules/redux": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.0.tgz", @@ -4477,6 +4426,323 @@ "uuid": "dist/bin/uuid" } }, + "node_modules/victory-area": { + "version": "36.6.7", + "resolved": "https://registry.npmjs.org/victory-area/-/victory-area-36.6.7.tgz", + "integrity": "sha512-bS8hu9aoKNX9Y1WEl3Z5uPhwrX1Tjf3TD5+ShYvTk4kk6Dz54mFp1+r4cNDc+65RB9dUeWAiLKqzQyD+DiFX4A==", + "dependencies": { + "lodash": "^4.17.19", + "prop-types": "^15.8.1", + "victory-core": "^36.6.7", + "victory-vendor": "^36.6.7" + }, + "peerDependencies": { + "react": ">=16.6.0" + } + }, + "node_modules/victory-axis": { + "version": "36.6.7", + "resolved": "https://registry.npmjs.org/victory-axis/-/victory-axis-36.6.7.tgz", + "integrity": "sha512-4tQkUOXR/hp+vG5sLOs8ePWsCCsaV7mnoOvXmn/CglXr89mWunUVPardwuqJ6pBKc9k+ND2i9E850xU7q56lww==", + "dependencies": { + "lodash": "^4.17.19", + "prop-types": "^15.8.1", + "victory-core": "^36.6.7" + }, + "peerDependencies": { + "react": ">=16.6.0" + } + }, + "node_modules/victory-bar": { + "version": "36.6.7", + "resolved": "https://registry.npmjs.org/victory-bar/-/victory-bar-36.6.7.tgz", + "integrity": "sha512-hINYnDwJEblJgFGHH1yWNLfi9Qv2GQluvsxkf6drWTOoHpTCIb9m+dxNoZZ+LAc0ABNbOWmSwyTYKcmyCk33eA==", + "dependencies": { + "lodash": "^4.17.19", + "prop-types": "^15.8.1", + "victory-core": "^36.6.7", + "victory-vendor": "^36.6.7" + }, + "peerDependencies": { + "react": ">=16.6.0" + } + }, + "node_modules/victory-brush-container": { + "version": "36.6.7", + "resolved": "https://registry.npmjs.org/victory-brush-container/-/victory-brush-container-36.6.7.tgz", + "integrity": "sha512-VmHEvwT4V06tMRLpjJI4sd0ARX+neCZTDN/156fWLTwjocN7uLxMP7FsmYAKjprT48z+Rctzrp4HtTcUO5OqNQ==", + "dependencies": { + "lodash": "^4.17.19", + "prop-types": "^15.8.1", + "react-fast-compare": "^3.2.0", + "victory-core": "^36.6.7" + }, + "peerDependencies": { + "react": ">=16.6.0" + } + }, + "node_modules/victory-chart": { + "version": "36.6.7", + "resolved": "https://registry.npmjs.org/victory-chart/-/victory-chart-36.6.7.tgz", + "integrity": "sha512-TvSFsXm9+UxnnlZDBFMPYqlPMpi8rDxGz/EmoudpePY91mzNViFcw3DWndHtivO93Cf4KAB6i5ThmTNHaRTD1g==", + "dependencies": { + "lodash": "^4.17.19", + "prop-types": "^15.8.1", + "react-fast-compare": "^3.2.0", + "victory-axis": "^36.6.7", + "victory-core": "^36.6.7", + "victory-polar-axis": "^36.6.7", + "victory-shared-events": "^36.6.7" + }, + "peerDependencies": { + "react": ">=16.6.0" + } + }, + "node_modules/victory-core": { + "version": "36.6.7", + "resolved": "https://registry.npmjs.org/victory-core/-/victory-core-36.6.7.tgz", + "integrity": "sha512-cpqjpVKk0DDCtCyT+LPaDqk+CxXL6lemRnarUn1DUYWcaUTHAYkdG8Gk2ExrPsKNw2mfpMCwlrvKSD6Bh/XXOA==", + "dependencies": { + "lodash": "^4.17.21", + "prop-types": "^15.8.1", + "react-fast-compare": "^3.2.0", + "victory-vendor": "^36.6.7" + }, + "peerDependencies": { + "react": ">=16.6.0" + } + }, + "node_modules/victory-create-container": { + "version": "36.6.7", + "resolved": "https://registry.npmjs.org/victory-create-container/-/victory-create-container-36.6.7.tgz", + "integrity": "sha512-yHi0EdMmqCgM7QAltDu70vo8LAYWd3qqLmbu7Z4ry0eQAhOSztaiNgHEttqKegLUrxZTzFHYqkhZqvg5akhZRw==", + "dependencies": { + "lodash": "^4.17.19", + "victory-brush-container": "^36.6.7", + "victory-core": "^36.6.7", + "victory-cursor-container": "^36.6.7", + "victory-selection-container": "^36.6.7", + "victory-voronoi-container": "^36.6.7", + "victory-zoom-container": "^36.6.7" + }, + "peerDependencies": { + "react": ">=16.6.0" + } + }, + "node_modules/victory-cursor-container": { + "version": "36.6.7", + "resolved": "https://registry.npmjs.org/victory-cursor-container/-/victory-cursor-container-36.6.7.tgz", + "integrity": "sha512-FmZ/49y6AcCmzHwUSlAttALwhQAdLUtW9aAbrTzBZHssT7hMe8loz7YnT080E+Fx3A25kpzmXXJSfC3wfMfoSA==", + "dependencies": { + "lodash": "^4.17.19", + "prop-types": "^15.8.1", + "victory-core": "^36.6.7" + }, + "peerDependencies": { + "react": ">=16.6.0" + } + }, + "node_modules/victory-errorbar": { + "version": "36.6.7", + "resolved": "https://registry.npmjs.org/victory-errorbar/-/victory-errorbar-36.6.7.tgz", + "integrity": "sha512-fa6MqjBi/HQ66rvBFzjw9UmGqlbFsyID0o8Q66PPNLT+RutYAQHCRMJoE1uNodFK/OhPEsAkyYiln+6ItxSkNQ==", + "dependencies": { + "lodash": "^4.17.19", + "prop-types": "^15.8.1", + "victory-core": "^36.6.7" + }, + "peerDependencies": { + "react": ">=16.6.0" + } + }, + "node_modules/victory-group": { + "version": "36.6.7", + "resolved": "https://registry.npmjs.org/victory-group/-/victory-group-36.6.7.tgz", + "integrity": "sha512-tscopmee4nN0uZABDk8FsG5eNk6UtA3oC+iYs6wOv61Jz80nLT2v/tH+ggvVubVnAUrLwQuiT1+ibi16frJaGQ==", + "dependencies": { + "lodash": "^4.17.19", + "prop-types": "^15.8.1", + "react-fast-compare": "^3.2.0", + "victory-core": "^36.6.7", + "victory-shared-events": "^36.6.7" + }, + "peerDependencies": { + "react": ">=16.6.0" + } + }, + "node_modules/victory-legend": { + "version": "36.6.7", + "resolved": "https://registry.npmjs.org/victory-legend/-/victory-legend-36.6.7.tgz", + "integrity": "sha512-UZMCVTiFJe+/um3cNwCxJmsTrdK5EVRu1jaNIom78UsaKmSmqRCsXRts1SkYvvlBG9dcdNCVXjL8YqHnKBO68A==", + "dependencies": { + "lodash": "^4.17.19", + "prop-types": "^15.8.1", + "victory-core": "^36.6.7" + }, + "peerDependencies": { + "react": ">=16.6.0" + } + }, + "node_modules/victory-line": { + "version": "36.6.7", + "resolved": "https://registry.npmjs.org/victory-line/-/victory-line-36.6.7.tgz", + "integrity": "sha512-U3WXpSMWWgWMeUzO1XVB3H6qCmzPpXQxhC4+qXtFVaxQX6iO59GsA6qw7PgABo4s1Vg35Qg5iQBj5PyXK8cRbw==", + "dependencies": { + "lodash": "^4.17.19", + "prop-types": "^15.8.1", + "victory-core": "^36.6.7", + "victory-vendor": "^36.6.7" + }, + "peerDependencies": { + "react": ">=16.6.0" + } + }, + "node_modules/victory-pie": { + "version": "36.6.7", + "resolved": "https://registry.npmjs.org/victory-pie/-/victory-pie-36.6.7.tgz", + "integrity": "sha512-SLkGRsONrB6ZndBYqrh7PfBlbh+8BLyGVCh+78qdm4HfTJ3IC/i19sRZDhpk5rFSrCYMbUktTBYC6b39qwt3ew==", + "dependencies": { + "lodash": "^4.17.19", + "prop-types": "^15.8.1", + "victory-core": "^36.6.7", + "victory-vendor": "^36.6.7" + }, + "peerDependencies": { + "react": ">=16.6.0" + } + }, + "node_modules/victory-polar-axis": { + "version": "36.6.7", + "resolved": "https://registry.npmjs.org/victory-polar-axis/-/victory-polar-axis-36.6.7.tgz", + "integrity": "sha512-+QTGRcnjT/8KUSzTP1K/WiLZzDPwqGfUOGRetAt9JMT/BLrQFeqVktdsv2B5qOkns+9M7QDqXSpmwkO1ldTsOw==", + "dependencies": { + "lodash": "^4.17.19", + "prop-types": "^15.8.1", + "victory-core": "^36.6.7" + }, + "peerDependencies": { + "react": ">=16.6.0" + } + }, + "node_modules/victory-scatter": { + "version": "36.6.7", + "resolved": "https://registry.npmjs.org/victory-scatter/-/victory-scatter-36.6.7.tgz", + "integrity": "sha512-pS99OGhxNaQD1GsdgVFUKuFC5x+upHDG1VNTl187iu+R4TT9Ut0MWoClZY1XxBDGnRcIPca9cLU+FRzCrl4TiA==", + "dependencies": { + "lodash": "^4.17.19", + "prop-types": "^15.8.1", + "victory-core": "^36.6.7" + }, + "peerDependencies": { + "react": ">=16.6.0" + } + }, + "node_modules/victory-selection-container": { + "version": "36.6.7", + "resolved": "https://registry.npmjs.org/victory-selection-container/-/victory-selection-container-36.6.7.tgz", + "integrity": "sha512-zKNd6ghaIP2b+sLCn2ZIFdAInWJO8cVTAjQeA17KwgZ4f5EeGogCYMBsmZeLeKVwZvkWtegqH9SfsTrYhPBpoQ==", + "dependencies": { + "lodash": "^4.17.19", + "prop-types": "^15.8.1", + "victory-core": "^36.6.7" + }, + "peerDependencies": { + "react": ">=16.6.0" + } + }, + "node_modules/victory-shared-events": { + "version": "36.6.7", + "resolved": "https://registry.npmjs.org/victory-shared-events/-/victory-shared-events-36.6.7.tgz", + "integrity": "sha512-G4Clm873xV2ckKRU7zXOhro1i/kljVg0+/AaMKxVctauu5tdFcNZr59sT22vDH4wnjQ48xLJBT+c6hM4WmGG2g==", + "dependencies": { + "json-stringify-safe": "^5.0.1", + "lodash": "^4.17.19", + "prop-types": "^15.8.1", + "react-fast-compare": "^3.2.0", + "victory-core": "^36.6.7" + }, + "peerDependencies": { + "react": ">=16.6.0" + } + }, + "node_modules/victory-stack": { + "version": "36.6.7", + "resolved": "https://registry.npmjs.org/victory-stack/-/victory-stack-36.6.7.tgz", + "integrity": "sha512-2Mda4IV8ru0azHjZ9YV2NuJ0DMkjgc4O17f4q1uU20v5U3rJGYfubxYX7qWv8VvaIldogzzXbAr9tRjJ39gvuA==", + "dependencies": { + "lodash": "^4.17.19", + "prop-types": "^15.8.1", + "react-fast-compare": "^3.2.0", + "victory-core": "^36.6.7", + "victory-shared-events": "^36.6.7" + }, + "peerDependencies": { + "react": ">=16.6.0" + } + }, + "node_modules/victory-tooltip": { + "version": "36.6.7", + "resolved": "https://registry.npmjs.org/victory-tooltip/-/victory-tooltip-36.6.7.tgz", + "integrity": "sha512-+HrYQfClC7TYkc+0lOff7x/vXcufEWVfxnuJ1C1gDJqNpxCfcOQ4iT5sNm9gdLwPn7vgaC/YlaKuo0wLJMfUUA==", + "dependencies": { + "lodash": "^4.17.19", + "prop-types": "^15.8.1", + "victory-core": "^36.6.7" + }, + "peerDependencies": { + "react": ">=16.6.0" + } + }, + "node_modules/victory-vendor": { + "version": "36.6.7", + "resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-36.6.7.tgz", + "integrity": "sha512-zCL7Pm6oyUHPjGKIimxHhybAKTcEhDRJpdfqxKGXQZX1DgOYeAwVhnag75Fgb6tBx4xm7aRg0Bg7gKGUaOFkmQ==", + "dependencies": { + "@types/d3-array": "^3.0.3", + "@types/d3-ease": "^3.0.0", + "@types/d3-interpolate": "^3.0.1", + "@types/d3-scale": "^4.0.2", + "@types/d3-shape": "^3.1.0", + "@types/d3-time": "^3.0.0", + "@types/d3-timer": "^3.0.0", + "d3-array": "^3.1.6", + "d3-ease": "^3.0.1", + "d3-interpolate": "^3.0.1", + "d3-scale": "^4.0.2", + "d3-shape": "^3.1.0", + "d3-time": "^3.0.0", + "d3-timer": "^3.0.1" + } + }, + "node_modules/victory-voronoi-container": { + "version": "36.6.7", + "resolved": "https://registry.npmjs.org/victory-voronoi-container/-/victory-voronoi-container-36.6.7.tgz", + "integrity": "sha512-dpwMb22HYLAxk8G9R9hxJa1hns6iK63ZbsRkKZfKgHfQh4E91tpu9oJ/UBEq/e4KKxfToKFVIFf33VOh/hDiKw==", + "dependencies": { + "delaunay-find": "0.0.6", + "lodash": "^4.17.19", + "prop-types": "^15.8.1", + "react-fast-compare": "^3.2.0", + "victory-core": "^36.6.7", + "victory-tooltip": "^36.6.7" + }, + "peerDependencies": { + "react": ">=16.6.0" + } + }, + "node_modules/victory-zoom-container": { + "version": "36.6.7", + "resolved": "https://registry.npmjs.org/victory-zoom-container/-/victory-zoom-container-36.6.7.tgz", + "integrity": "sha512-VghZUdjI2LVIcgu7942CmE9p54bvrN/+R69fiworyJF/wBS/QKzsIVDmyY+TyHMznuEKtO2uJgdvu/tp+zolrw==", + "dependencies": { + "lodash": "^4.17.19", + "prop-types": "^15.8.1", + "victory-core": "^36.6.7" + }, + "peerDependencies": { + "react": ">=16.6.0" + } + }, "node_modules/warning": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", @@ -4808,6 +5074,41 @@ "fastq": "^1.6.0" } }, + "@patternfly/react-charts": { + "version": "6.88.7", + "resolved": "https://registry.npmjs.org/@patternfly/react-charts/-/react-charts-6.88.7.tgz", + "integrity": "sha512-1SGDHfTmjH3c54ym1i1d1SH1DGArn96Fwkv1woOTpRhNgBoz6TkoDJGHfpX6UUyun1uqDMUdNP8tOnb9SITuvQ==", + "requires": { + "@patternfly/react-styles": "^4.85.7", + "@patternfly/react-tokens": "^4.87.7", + "hoist-non-react-statics": "^3.3.0", + "lodash": "^4.17.19", + "tslib": "^2.0.0", + "victory-area": "^36.2.1", + "victory-axis": "^36.2.1", + "victory-bar": "^36.2.1", + "victory-chart": "^36.2.1", + "victory-core": "^36.2.1", + "victory-create-container": "^36.2.1", + "victory-cursor-container": "^36.2.1", + "victory-group": "^36.2.1", + "victory-legend": "^36.2.1", + "victory-line": "^36.2.1", + "victory-pie": "^36.2.1", + "victory-scatter": "^36.2.1", + "victory-stack": "^36.2.1", + "victory-tooltip": "^36.2.1", + "victory-voronoi-container": "^36.2.1", + "victory-zoom-container": "^36.2.1" + }, + "dependencies": { + "tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + } + } + }, "@patternfly/react-core": { "version": "4.235.7", "resolved": "https://registry.npmjs.org/@patternfly/react-core/-/react-core-4.235.7.tgz", @@ -5015,11 +5316,21 @@ } } }, + "@types/d3-array": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.0.3.tgz", + "integrity": "sha512-Reoy+pKnvsksN0lQUlcH6dOGjRZ/3WRwXR//m+/8lt1BXeI4xyaUZoqULNjyXXRuh0Mj4LNpkCvhUpQlY3X5xQ==" + }, "@types/d3-color": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.0.tgz", "integrity": "sha512-HKuicPHJuvPgCD+np6Se9MQvS6OCbJmOjGvylzMJRlDwUXjKTTXs6Pwgk79O09Vj/ho3u1ofXnhFOaEWWPrlwA==" }, + "@types/d3-ease": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.0.tgz", + "integrity": "sha512-aMo4eaAOijJjA6uU+GIeW018dvy9+oH5Y2VPPzjjfxevvGQ/oRDs+tfYC9b50Q4BygRR8yE2QCLsrT0WtAVseA==" + }, "@types/d3-interpolate": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.1.tgz", @@ -5054,6 +5365,11 @@ "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.0.tgz", "integrity": "sha512-sZLCdHvBUcNby1cB6Fd3ZBrABbjz3v1Vm90nysCQ6Vt7vd6e/h9Lt7SiJUoEX0l4Dzc7P5llKyhqSi1ycSf1Hg==" }, + "@types/d3-timer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.0.tgz", + "integrity": "sha512-HNB/9GHqu7Fo8AQiugyJbv6ZxYz58wef0esl4Mv828w1ZKpAshw/uFWVDUcIB9KKFeFKoxS3cHY07FFgtTRZ1g==" + }, "@types/hoist-non-react-statics": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", @@ -5209,11 +5525,6 @@ "picomatch": "^2.0.4" } }, - "approximate-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/approximate-number/-/approximate-number-2.1.0.tgz", - "integrity": "sha512-EioK6nto/hEnwaJ7d/TG1WOZ9o0zTyIFVP4Lk7zzR/3I4O7ivkBNo7EvLC2Xh2j2HD/cb9sUqXHdexfGXCXYDA==" - }, "argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -5407,11 +5718,6 @@ "readdirp": "~3.6.0" } }, - "classnames": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", - "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" - }, "clsx": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", @@ -5469,11 +5775,6 @@ "which": "^2.0.1" } }, - "css-unit-converter": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/css-unit-converter/-/css-unit-converter-1.1.2.tgz", - "integrity": "sha512-IiJwMC8rdZE0+xiEZHeru6YoONC4rfPMqGm2W85jMIbkFvv5nFTwJVFHam2eFrN6txmoUYFAFXiv8ICVeTO0MA==" - }, "csstype": { "version": "3.0.11", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.11.tgz", @@ -5492,6 +5793,11 @@ "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==" }, + "d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==" + }, "d3-format": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", @@ -5546,6 +5852,11 @@ "d3-time": "1 - 3" } }, + "d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==" + }, "damerau-levenshtein": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", @@ -5566,11 +5877,6 @@ "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.0.tgz", "integrity": "sha512-Nv6ENEzyPQ6AItkGwLE2PGKinZZ9g59vSh2BeH6NqPu0OTKZ5ruJsVqh/orbAnqXc9pBbgXAIrc2EyaCj8NpGg==" }, - "decimal.js-light": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz", - "integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==" - }, "deep-diff": { "version": "0.3.8", "resolved": "https://registry.npmjs.org/deep-diff/-/deep-diff-0.3.8.tgz", @@ -5592,6 +5898,19 @@ "object-keys": "^1.1.1" } }, + "delaunator": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-4.0.1.tgz", + "integrity": "sha512-WNPWi1IRKZfCt/qIDMfERkDp93+iZEmOxN2yy4Jg+Xhv8SLk2UTqqbe1sfiipn0and9QrE914/ihdx82Y/Giag==" + }, + "delaunay-find": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/delaunay-find/-/delaunay-find-0.0.6.tgz", + "integrity": "sha512-1+almjfrnR7ZamBk0q3Nhg6lqSe6Le4vL0WJDSMx4IDbQwTpUTXPjxC00lqLBT8MYsJpPCbI16sIkw9cPsbi7Q==", + "requires": { + "delaunator": "^4.0.0" + } + }, "detect-node": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", @@ -5615,14 +5934,6 @@ "esutils": "^2.0.2" } }, - "dom-helpers": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.4.0.tgz", - "integrity": "sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==", - "requires": { - "@babel/runtime": "^7.1.2" - } - }, "emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", @@ -6057,22 +6368,12 @@ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, - "eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" - }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, - "fast-equals": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-2.0.4.tgz", - "integrity": "sha512-caj/ZmjHljPrZtbzJ3kfH5ia/k4mTJe/qSiXAGzxZWRZgsgDV0cvNaQULqUX8t0/JVlzzEdYOwCN5DmzTxoD4w==" - }, "fast-glob": { "version": "3.2.11", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", @@ -6591,6 +6892,11 @@ "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", "dev": true }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" + }, "json5": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", @@ -6990,11 +7296,6 @@ "source-map-js": "^1.0.2" } }, - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, "prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -7072,6 +7373,11 @@ "prop-types-extra": "^1.1.0" } }, + "react-fast-compare": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz", + "integrity": "sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==" + }, "react-hotkeys-hook": { "version": "3.4.7", "resolved": "https://registry.npmjs.org/react-hotkeys-hook/-/react-hotkeys-hook-3.4.7.tgz", @@ -7095,11 +7401,6 @@ "scheduler": "^0.20.2" } }, - "react-lifecycles-compat": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", - "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" - }, "react-query": { "version": "3.39.2", "resolved": "https://registry.npmjs.org/react-query/-/react-query-3.39.2.tgz", @@ -7140,34 +7441,6 @@ } } }, - "react-resize-detector": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/react-resize-detector/-/react-resize-detector-7.1.2.tgz", - "integrity": "sha512-zXnPJ2m8+6oq9Nn8zsep/orts9vQv3elrpA+R8XTcW7DVVUJ9vwDwMXaBtykAYjMnkCIaOoK9vObyR7ZgFNlOw==", - "requires": { - "lodash": "^4.17.21" - } - }, - "react-smooth": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-2.0.1.tgz", - "integrity": "sha512-Own9TA0GPPf3as4vSwFhDouVfXP15ie/wIHklhyKBH5AN6NFtdk0UpHBnonV11BtqDkAWlt40MOUc+5srmW7NA==", - "requires": { - "fast-equals": "^2.0.0", - "react-transition-group": "2.9.0" - } - }, - "react-transition-group": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.9.0.tgz", - "integrity": "sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg==", - "requires": { - "dom-helpers": "^3.4.0", - "loose-envify": "^1.4.0", - "prop-types": "^15.6.2", - "react-lifecycles-compat": "^3.0.4" - } - }, "readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -7176,44 +7449,6 @@ "picomatch": "^2.2.1" } }, - "recharts": { - "version": "2.1.14", - "resolved": "https://registry.npmjs.org/recharts/-/recharts-2.1.14.tgz", - "integrity": "sha512-GDmDDPEmRhGb6O41OfJUKh/RFYh3QMtEdaNuXOnVtJN8wiifo41MvIHHzrjf7Vp7/yJYFsGaXnCElzM5H7SPmQ==", - "requires": { - "@types/d3-interpolate": "^3.0.1", - "@types/d3-scale": "^4.0.2", - "@types/d3-shape": "^3.1.0", - "classnames": "^2.2.5", - "d3-interpolate": "^3.0.1", - "d3-scale": "^4.0.2", - "d3-shape": "^3.1.0", - "eventemitter3": "^4.0.1", - "lodash": "^4.17.19", - "react-is": "^16.10.2", - "react-resize-detector": "^7.1.2", - "react-smooth": "^2.0.1", - "recharts-scale": "^0.4.4", - "reduce-css-calc": "^2.1.8" - } - }, - "recharts-scale": { - "version": "0.4.5", - "resolved": "https://registry.npmjs.org/recharts-scale/-/recharts-scale-0.4.5.tgz", - "integrity": "sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w==", - "requires": { - "decimal.js-light": "^2.4.1" - } - }, - "reduce-css-calc": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-2.1.8.tgz", - "integrity": "sha512-8liAVezDmUcH+tdzoEGrhfbGcP7nOV4NkGE3a74+qqvE7nt9i4sKLGBuZNOnpI4WiGksiNPklZxva80061QiPg==", - "requires": { - "css-unit-converter": "^1.1.1", - "postcss-value-parser": "^3.3.0" - } - }, "redux": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.0.tgz", @@ -7630,6 +7865,260 @@ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" }, + "victory-area": { + "version": "36.6.7", + "resolved": "https://registry.npmjs.org/victory-area/-/victory-area-36.6.7.tgz", + "integrity": "sha512-bS8hu9aoKNX9Y1WEl3Z5uPhwrX1Tjf3TD5+ShYvTk4kk6Dz54mFp1+r4cNDc+65RB9dUeWAiLKqzQyD+DiFX4A==", + "requires": { + "lodash": "^4.17.19", + "prop-types": "^15.8.1", + "victory-core": "^36.6.7", + "victory-vendor": "^36.6.7" + } + }, + "victory-axis": { + "version": "36.6.7", + "resolved": "https://registry.npmjs.org/victory-axis/-/victory-axis-36.6.7.tgz", + "integrity": "sha512-4tQkUOXR/hp+vG5sLOs8ePWsCCsaV7mnoOvXmn/CglXr89mWunUVPardwuqJ6pBKc9k+ND2i9E850xU7q56lww==", + "requires": { + "lodash": "^4.17.19", + "prop-types": "^15.8.1", + "victory-core": "^36.6.7" + } + }, + "victory-bar": { + "version": "36.6.7", + "resolved": "https://registry.npmjs.org/victory-bar/-/victory-bar-36.6.7.tgz", + "integrity": "sha512-hINYnDwJEblJgFGHH1yWNLfi9Qv2GQluvsxkf6drWTOoHpTCIb9m+dxNoZZ+LAc0ABNbOWmSwyTYKcmyCk33eA==", + "requires": { + "lodash": "^4.17.19", + "prop-types": "^15.8.1", + "victory-core": "^36.6.7", + "victory-vendor": "^36.6.7" + } + }, + "victory-brush-container": { + "version": "36.6.7", + "resolved": "https://registry.npmjs.org/victory-brush-container/-/victory-brush-container-36.6.7.tgz", + "integrity": "sha512-VmHEvwT4V06tMRLpjJI4sd0ARX+neCZTDN/156fWLTwjocN7uLxMP7FsmYAKjprT48z+Rctzrp4HtTcUO5OqNQ==", + "requires": { + "lodash": "^4.17.19", + "prop-types": "^15.8.1", + "react-fast-compare": "^3.2.0", + "victory-core": "^36.6.7" + } + }, + "victory-chart": { + "version": "36.6.7", + "resolved": "https://registry.npmjs.org/victory-chart/-/victory-chart-36.6.7.tgz", + "integrity": "sha512-TvSFsXm9+UxnnlZDBFMPYqlPMpi8rDxGz/EmoudpePY91mzNViFcw3DWndHtivO93Cf4KAB6i5ThmTNHaRTD1g==", + "requires": { + "lodash": "^4.17.19", + "prop-types": "^15.8.1", + "react-fast-compare": "^3.2.0", + "victory-axis": "^36.6.7", + "victory-core": "^36.6.7", + "victory-polar-axis": "^36.6.7", + "victory-shared-events": "^36.6.7" + } + }, + "victory-core": { + "version": "36.6.7", + "resolved": "https://registry.npmjs.org/victory-core/-/victory-core-36.6.7.tgz", + "integrity": "sha512-cpqjpVKk0DDCtCyT+LPaDqk+CxXL6lemRnarUn1DUYWcaUTHAYkdG8Gk2ExrPsKNw2mfpMCwlrvKSD6Bh/XXOA==", + "requires": { + "lodash": "^4.17.21", + "prop-types": "^15.8.1", + "react-fast-compare": "^3.2.0", + "victory-vendor": "^36.6.7" + } + }, + "victory-create-container": { + "version": "36.6.7", + "resolved": "https://registry.npmjs.org/victory-create-container/-/victory-create-container-36.6.7.tgz", + "integrity": "sha512-yHi0EdMmqCgM7QAltDu70vo8LAYWd3qqLmbu7Z4ry0eQAhOSztaiNgHEttqKegLUrxZTzFHYqkhZqvg5akhZRw==", + "requires": { + "lodash": "^4.17.19", + "victory-brush-container": "^36.6.7", + "victory-core": "^36.6.7", + "victory-cursor-container": "^36.6.7", + "victory-selection-container": "^36.6.7", + "victory-voronoi-container": "^36.6.7", + "victory-zoom-container": "^36.6.7" + } + }, + "victory-cursor-container": { + "version": "36.6.7", + "resolved": "https://registry.npmjs.org/victory-cursor-container/-/victory-cursor-container-36.6.7.tgz", + "integrity": "sha512-FmZ/49y6AcCmzHwUSlAttALwhQAdLUtW9aAbrTzBZHssT7hMe8loz7YnT080E+Fx3A25kpzmXXJSfC3wfMfoSA==", + "requires": { + "lodash": "^4.17.19", + "prop-types": "^15.8.1", + "victory-core": "^36.6.7" + } + }, + "victory-errorbar": { + "version": "36.6.7", + "resolved": "https://registry.npmjs.org/victory-errorbar/-/victory-errorbar-36.6.7.tgz", + "integrity": "sha512-fa6MqjBi/HQ66rvBFzjw9UmGqlbFsyID0o8Q66PPNLT+RutYAQHCRMJoE1uNodFK/OhPEsAkyYiln+6ItxSkNQ==", + "requires": { + "lodash": "^4.17.19", + "prop-types": "^15.8.1", + "victory-core": "^36.6.7" + } + }, + "victory-group": { + "version": "36.6.7", + "resolved": "https://registry.npmjs.org/victory-group/-/victory-group-36.6.7.tgz", + "integrity": "sha512-tscopmee4nN0uZABDk8FsG5eNk6UtA3oC+iYs6wOv61Jz80nLT2v/tH+ggvVubVnAUrLwQuiT1+ibi16frJaGQ==", + "requires": { + "lodash": "^4.17.19", + "prop-types": "^15.8.1", + "react-fast-compare": "^3.2.0", + "victory-core": "^36.6.7", + "victory-shared-events": "^36.6.7" + } + }, + "victory-legend": { + "version": "36.6.7", + "resolved": "https://registry.npmjs.org/victory-legend/-/victory-legend-36.6.7.tgz", + "integrity": "sha512-UZMCVTiFJe+/um3cNwCxJmsTrdK5EVRu1jaNIom78UsaKmSmqRCsXRts1SkYvvlBG9dcdNCVXjL8YqHnKBO68A==", + "requires": { + "lodash": "^4.17.19", + "prop-types": "^15.8.1", + "victory-core": "^36.6.7" + } + }, + "victory-line": { + "version": "36.6.7", + "resolved": "https://registry.npmjs.org/victory-line/-/victory-line-36.6.7.tgz", + "integrity": "sha512-U3WXpSMWWgWMeUzO1XVB3H6qCmzPpXQxhC4+qXtFVaxQX6iO59GsA6qw7PgABo4s1Vg35Qg5iQBj5PyXK8cRbw==", + "requires": { + "lodash": "^4.17.19", + "prop-types": "^15.8.1", + "victory-core": "^36.6.7", + "victory-vendor": "^36.6.7" + } + }, + "victory-pie": { + "version": "36.6.7", + "resolved": "https://registry.npmjs.org/victory-pie/-/victory-pie-36.6.7.tgz", + "integrity": "sha512-SLkGRsONrB6ZndBYqrh7PfBlbh+8BLyGVCh+78qdm4HfTJ3IC/i19sRZDhpk5rFSrCYMbUktTBYC6b39qwt3ew==", + "requires": { + "lodash": "^4.17.19", + "prop-types": "^15.8.1", + "victory-core": "^36.6.7", + "victory-vendor": "^36.6.7" + } + }, + "victory-polar-axis": { + "version": "36.6.7", + "resolved": "https://registry.npmjs.org/victory-polar-axis/-/victory-polar-axis-36.6.7.tgz", + "integrity": "sha512-+QTGRcnjT/8KUSzTP1K/WiLZzDPwqGfUOGRetAt9JMT/BLrQFeqVktdsv2B5qOkns+9M7QDqXSpmwkO1ldTsOw==", + "requires": { + "lodash": "^4.17.19", + "prop-types": "^15.8.1", + "victory-core": "^36.6.7" + } + }, + "victory-scatter": { + "version": "36.6.7", + "resolved": "https://registry.npmjs.org/victory-scatter/-/victory-scatter-36.6.7.tgz", + "integrity": "sha512-pS99OGhxNaQD1GsdgVFUKuFC5x+upHDG1VNTl187iu+R4TT9Ut0MWoClZY1XxBDGnRcIPca9cLU+FRzCrl4TiA==", + "requires": { + "lodash": "^4.17.19", + "prop-types": "^15.8.1", + "victory-core": "^36.6.7" + } + }, + "victory-selection-container": { + "version": "36.6.7", + "resolved": "https://registry.npmjs.org/victory-selection-container/-/victory-selection-container-36.6.7.tgz", + "integrity": "sha512-zKNd6ghaIP2b+sLCn2ZIFdAInWJO8cVTAjQeA17KwgZ4f5EeGogCYMBsmZeLeKVwZvkWtegqH9SfsTrYhPBpoQ==", + "requires": { + "lodash": "^4.17.19", + "prop-types": "^15.8.1", + "victory-core": "^36.6.7" + } + }, + "victory-shared-events": { + "version": "36.6.7", + "resolved": "https://registry.npmjs.org/victory-shared-events/-/victory-shared-events-36.6.7.tgz", + "integrity": "sha512-G4Clm873xV2ckKRU7zXOhro1i/kljVg0+/AaMKxVctauu5tdFcNZr59sT22vDH4wnjQ48xLJBT+c6hM4WmGG2g==", + "requires": { + "json-stringify-safe": "^5.0.1", + "lodash": "^4.17.19", + "prop-types": "^15.8.1", + "react-fast-compare": "^3.2.0", + "victory-core": "^36.6.7" + } + }, + "victory-stack": { + "version": "36.6.7", + "resolved": "https://registry.npmjs.org/victory-stack/-/victory-stack-36.6.7.tgz", + "integrity": "sha512-2Mda4IV8ru0azHjZ9YV2NuJ0DMkjgc4O17f4q1uU20v5U3rJGYfubxYX7qWv8VvaIldogzzXbAr9tRjJ39gvuA==", + "requires": { + "lodash": "^4.17.19", + "prop-types": "^15.8.1", + "react-fast-compare": "^3.2.0", + "victory-core": "^36.6.7", + "victory-shared-events": "^36.6.7" + } + }, + "victory-tooltip": { + "version": "36.6.7", + "resolved": "https://registry.npmjs.org/victory-tooltip/-/victory-tooltip-36.6.7.tgz", + "integrity": "sha512-+HrYQfClC7TYkc+0lOff7x/vXcufEWVfxnuJ1C1gDJqNpxCfcOQ4iT5sNm9gdLwPn7vgaC/YlaKuo0wLJMfUUA==", + "requires": { + "lodash": "^4.17.19", + "prop-types": "^15.8.1", + "victory-core": "^36.6.7" + } + }, + "victory-vendor": { + "version": "36.6.7", + "resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-36.6.7.tgz", + "integrity": "sha512-zCL7Pm6oyUHPjGKIimxHhybAKTcEhDRJpdfqxKGXQZX1DgOYeAwVhnag75Fgb6tBx4xm7aRg0Bg7gKGUaOFkmQ==", + "requires": { + "@types/d3-array": "^3.0.3", + "@types/d3-ease": "^3.0.0", + "@types/d3-interpolate": "^3.0.1", + "@types/d3-scale": "^4.0.2", + "@types/d3-shape": "^3.1.0", + "@types/d3-time": "^3.0.0", + "@types/d3-timer": "^3.0.0", + "d3-array": "^3.1.6", + "d3-ease": "^3.0.1", + "d3-interpolate": "^3.0.1", + "d3-scale": "^4.0.2", + "d3-shape": "^3.1.0", + "d3-time": "^3.0.0", + "d3-timer": "^3.0.1" + } + }, + "victory-voronoi-container": { + "version": "36.6.7", + "resolved": "https://registry.npmjs.org/victory-voronoi-container/-/victory-voronoi-container-36.6.7.tgz", + "integrity": "sha512-dpwMb22HYLAxk8G9R9hxJa1hns6iK63ZbsRkKZfKgHfQh4E91tpu9oJ/UBEq/e4KKxfToKFVIFf33VOh/hDiKw==", + "requires": { + "delaunay-find": "0.0.6", + "lodash": "^4.17.19", + "prop-types": "^15.8.1", + "react-fast-compare": "^3.2.0", + "victory-core": "^36.6.7", + "victory-tooltip": "^36.6.7" + } + }, + "victory-zoom-container": { + "version": "36.6.7", + "resolved": "https://registry.npmjs.org/victory-zoom-container/-/victory-zoom-container-36.6.7.tgz", + "integrity": "sha512-VghZUdjI2LVIcgu7942CmE9p54bvrN/+R69fiworyJF/wBS/QKzsIVDmyY+TyHMznuEKtO2uJgdvu/tp+zolrw==", + "requires": { + "lodash": "^4.17.19", + "prop-types": "^15.8.1", + "victory-core": "^36.6.7" + } + }, "warning": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", diff --git a/opendc-web/opendc-web-ui/package.json b/opendc-web/opendc-web-ui/package.json index c98c5458..a4cac1be 100644 --- a/opendc-web/opendc-web-ui/package.json +++ b/opendc-web/opendc-web-ui/package.json @@ -24,9 +24,9 @@ "@patternfly/react-core": "^4.235.7", "@patternfly/react-icons": "^4.86.7", "@patternfly/react-table": "^4.104.7", + "@patternfly/react-charts": "^6.88.7", "@sentry/react": "^6.19.7", "@sentry/tracing": "^6.19.7", - "approximate-number": "^2.1.0", "clsx": "^1.2.1", "immer": "^9.0.15", "konva": "^8.3.12", @@ -42,7 +42,6 @@ "react-konva": "^17.0.2-6", "react-query": "^3.39.2", "react-redux": "^8.0.2", - "recharts": "^2.1.14", "redux": "^4.2.0", "redux-logger": "^3.0.6", "redux-saga": "^1.2.1", @@ -50,7 +49,8 @@ "sass": "^1.54.9", "svgsaver": "^0.9.0", "use-resize-observer": "^9.0.2", - "uuid": "^8.3.2" + "uuid": "^8.3.2", + "victory-errorbar": "^36.6.7" }, "devDependencies": { "eslint": "^8.23.1", diff --git a/opendc-web/opendc-web-ui/src/components/portfolios/PortfolioResults.js b/opendc-web/opendc-web-ui/src/components/portfolios/PortfolioResults.js index 33604896..f50105ed 100644 --- a/opendc-web/opendc-web-ui/src/components/portfolios/PortfolioResults.js +++ b/opendc-web/opendc-web-ui/src/components/portfolios/PortfolioResults.js @@ -20,12 +20,11 @@ * SOFTWARE. */ +import { mean, std } from 'mathjs' import React, { useMemo } from 'react' import PropTypes from 'prop-types' -import { Bar, CartesianGrid, ComposedChart, ErrorBar, ResponsiveContainer, Scatter, XAxis, YAxis } from 'recharts' -import { METRIC_NAMES, METRIC_UNITS } from '../../util/available-metrics' -import { mean, std } from 'mathjs' -import approx from 'approximate-number' +import { VictoryErrorBar } from 'victory-errorbar' +import { METRIC_NAMES, METRIC_UNITS, AVAILABLE_METRICS } from '../../util/available-metrics' import { Bullseye, Card, @@ -41,6 +40,7 @@ import { Spinner, Title, } from '@patternfly/react-core' +import { Chart, ChartAxis, ChartBar, ChartTooltip } from '@patternfly/react-charts' import { ErrorCircleOIcon, CubesIcon } from '@patternfly/react-icons' import { usePortfolio } from '../../data/project' import PortfolioResultInfo from './PortfolioResultInfo' @@ -48,7 +48,28 @@ import NewScenario from './NewScenario' function PortfolioResults({ projectId, portfolioId }) { const { status, data: portfolio } = usePortfolio(projectId, portfolioId) - const scenarios = portfolio?.scenarios ?? [] + const scenarios = useMemo(() => portfolio?.scenarios ?? [], [portfolio]) + + const label = ({ datum }) => + `${datum.x}: ${datum.y.toLocaleString()} ± ${datum.errorY.toLocaleString()} ${METRIC_UNITS[datum.metric]}` + const selectedMetrics = new Set(portfolio?.targets?.metrics ?? []) + const dataPerMetric = useMemo(() => { + const dataPerMetric = {} + AVAILABLE_METRICS.forEach((metric) => { + dataPerMetric[metric] = scenarios + .filter((scenario) => scenario.job?.results) + .map((scenario) => ({ + metric, + x: scenario.name, + y: mean(scenario.job.results[metric]), + errorY: std(scenario.job.results[metric]), + label, + })) + }) + return dataPerMetric + }, [scenarios]) + + const categories = useMemo(() => ({ x: scenarios.map((s) => s.name).reverse() }), [scenarios]) if (status === 'loading') { return ( @@ -93,62 +114,57 @@ function PortfolioResults({ projectId, portfolioId }) { ) } - const metrics = portfolio?.targets?.metrics ?? [] - const dataPerMetric = useMemo(() => { - const dataPerMetric = {} - metrics.forEach((metric) => { - dataPerMetric[metric] = scenarios - .filter((scenario) => scenario.job?.results) - .map((scenario) => ({ - name: scenario.name, - value: mean(scenario.job.results[metric]), - errorX: std(scenario.job.results[metric]), - })) - }) - return dataPerMetric - }, [scenarios, metrics]) - return ( - {metrics.map((metric) => ( - - - - - - - {METRIC_NAMES[metric]} - - - - - - approx(tick)} - label={{ value: METRIC_UNITS[metric], position: 'bottom', offset: 0 }} - type="number" - /> - - - - + selectedMetrics.has(metric) && ( + + + + + + + {METRIC_NAMES[metric]} + + + + + + } + barWidth={25} + horizontal + /> + d.errorY} + labelComponent={<>} + horizontal /> - - - - - - - ))} + + + + + ) + )} ) } diff --git a/opendc-web/opendc-web-ui/src/pages/projects/[project]/portfolios/[portfolio].js b/opendc-web/opendc-web-ui/src/pages/projects/[project]/portfolios/[portfolio].js index 460785c1..615529e7 100644 --- a/opendc-web/opendc-web-ui/src/pages/projects/[project]/portfolios/[portfolio].js +++ b/opendc-web/opendc-web-ui/src/pages/projects/[project]/portfolios/[portfolio].js @@ -58,7 +58,6 @@ function Portfolio() { const resultsRef = useRef(null) const { data: portfolio } = usePortfolio(projectId, portfolioNumber) - const project = portfolio?.project const breadcrumb = ( @@ -94,7 +93,7 @@ function Portfolio() { Portfolio - +