Ver código fonte

Implemented shared tooltip

jnfrati 4 anos atrás
pai
commit
d335c72fbb

+ 733 - 0
dashboard/package-lock.json

@@ -274,6 +274,99 @@
         "react-is": "^16.8.0 || ^17.0.0"
       }
     },
+    "@react-spring/animated": {
+      "version": "9.2.4",
+      "resolved": "https://registry.npmjs.org/@react-spring/animated/-/animated-9.2.4.tgz",
+      "integrity": "sha512-AfV6ZM8pCCAT29GY5C8/1bOPjZrv/7kD0vedjiE/tEYvNDwg9GlscrvsTViWR2XykJoYrDfdkYArrldWpsCJ5g==",
+      "requires": {
+        "@react-spring/shared": "~9.2.0",
+        "@react-spring/types": "~9.2.0"
+      }
+    },
+    "@react-spring/core": {
+      "version": "9.2.4",
+      "resolved": "https://registry.npmjs.org/@react-spring/core/-/core-9.2.4.tgz",
+      "integrity": "sha512-R+PwyfsjiuYCWqaTTfCpYpRmsP0h87RNm7uxC1Uxy7QAHUfHEm2sAHn+AdHPwq/MbVwDssVT8C5yf2WGcqiXGg==",
+      "requires": {
+        "@react-spring/animated": "~9.2.0",
+        "@react-spring/shared": "~9.2.0",
+        "@react-spring/types": "~9.2.0"
+      }
+    },
+    "@react-spring/konva": {
+      "version": "9.2.4",
+      "resolved": "https://registry.npmjs.org/@react-spring/konva/-/konva-9.2.4.tgz",
+      "integrity": "sha512-19anDOIkfjcydDTfGgVIuZ3lruZxKubYGs9oHCswaP8SRLj7c1kkopJHUr/S4LXGxiIdqdF0XucWm0iTEPEq4w==",
+      "requires": {
+        "@react-spring/animated": "~9.2.0",
+        "@react-spring/core": "~9.2.0",
+        "@react-spring/shared": "~9.2.0",
+        "@react-spring/types": "~9.2.0"
+      }
+    },
+    "@react-spring/native": {
+      "version": "9.2.4",
+      "resolved": "https://registry.npmjs.org/@react-spring/native/-/native-9.2.4.tgz",
+      "integrity": "sha512-xKJWKh5qOhSclpL3iuGwJRLoZzTNvlBEnIrMs8yh8xvX6z9Lmnu4uGu5DpfrnM1GzBvRoktoCoLEx/VcEYFSng==",
+      "requires": {
+        "@react-spring/animated": "~9.2.0",
+        "@react-spring/core": "~9.2.0",
+        "@react-spring/shared": "~9.2.0",
+        "@react-spring/types": "~9.2.0"
+      }
+    },
+    "@react-spring/rafz": {
+      "version": "9.2.4",
+      "resolved": "https://registry.npmjs.org/@react-spring/rafz/-/rafz-9.2.4.tgz",
+      "integrity": "sha512-SOKf9eue+vAX+DGo7kWYNl9i9J3gPUlQjifIcV9Bzw9h3i30wPOOP0TjS7iMG/kLp2cdHQYDNFte6nt23VAZkQ=="
+    },
+    "@react-spring/shared": {
+      "version": "9.2.4",
+      "resolved": "https://registry.npmjs.org/@react-spring/shared/-/shared-9.2.4.tgz",
+      "integrity": "sha512-ZEr4l2BxmyFRUvRA2VCkPfCJii4E7cGkwbjmTBx1EmcGrOnde/V2eF5dxqCTY3k35QuCegkrWe0coRJVkh8q2Q==",
+      "requires": {
+        "@react-spring/rafz": "~9.2.0",
+        "@react-spring/types": "~9.2.0"
+      }
+    },
+    "@react-spring/three": {
+      "version": "9.2.4",
+      "resolved": "https://registry.npmjs.org/@react-spring/three/-/three-9.2.4.tgz",
+      "integrity": "sha512-ljFig7XW099VWwRPKPUf+4yYLivp/sSWXN3oO5SJOF/9BSoV1quS/9chZ5Myl5J14od3CsHf89Tv4FdlX5kHlA==",
+      "requires": {
+        "@react-spring/animated": "~9.2.0",
+        "@react-spring/core": "~9.2.0",
+        "@react-spring/shared": "~9.2.0",
+        "@react-spring/types": "~9.2.0"
+      }
+    },
+    "@react-spring/types": {
+      "version": "9.2.4",
+      "resolved": "https://registry.npmjs.org/@react-spring/types/-/types-9.2.4.tgz",
+      "integrity": "sha512-zHUXrWO8nweUN/ISjrjqU7GgXXvoEbFca1CgiE0TY0H/dqJb3l+Rhx8ecPVNYimzFg3ZZ1/T0egpLop8SOv4aA=="
+    },
+    "@react-spring/web": {
+      "version": "9.2.4",
+      "resolved": "https://registry.npmjs.org/@react-spring/web/-/web-9.2.4.tgz",
+      "integrity": "sha512-vtPvOalLFvuju/MDBtoSnCyt0xXSL6Amyv82fljOuWPl1yGd4M1WteijnYL9Zlriljl0a3oXcPunAVYTD9dbDQ==",
+      "requires": {
+        "@react-spring/animated": "~9.2.0",
+        "@react-spring/core": "~9.2.0",
+        "@react-spring/shared": "~9.2.0",
+        "@react-spring/types": "~9.2.0"
+      }
+    },
+    "@react-spring/zdog": {
+      "version": "9.2.4",
+      "resolved": "https://registry.npmjs.org/@react-spring/zdog/-/zdog-9.2.4.tgz",
+      "integrity": "sha512-rv7ptedS37SHr6yuCbRkUErAzAhebdgt8f4KUtZWzseC+7qLNkaZWf+uujgsb881qAuX9b9yz8rre9UKeYepgw==",
+      "requires": {
+        "@react-spring/animated": "~9.2.0",
+        "@react-spring/core": "~9.2.0",
+        "@react-spring/shared": "~9.2.0",
+        "@react-spring/types": "~9.2.0"
+      }
+    },
     "@sheerun/mutationobserver-shim": {
       "version": "0.3.3",
       "resolved": "https://registry.npmjs.org/@sheerun/mutationobserver-shim/-/mutationobserver-shim-0.3.3.tgz",
@@ -484,6 +577,11 @@
       "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-3.0.0.tgz",
       "integrity": "sha512-UpLg1mn/8PLyjr+J/JwdQJM/GzysMvv2CS8y+WYAL5K0+wbvXv/pPSLEfdNaprCZsGcXTxPsFMy8QtkYv9ueew=="
     },
+    "@types/d3-voronoi": {
+      "version": "1.1.9",
+      "resolved": "https://registry.npmjs.org/@types/d3-voronoi/-/d3-voronoi-1.1.9.tgz",
+      "integrity": "sha512-DExNQkaHd1F3dFPvGA/Aw2NGyjMln6E9QzsiqOcBgnE+VInYnFBHBBySbZQts6z6xD+5jTfKCP7M4OqMyVjdwQ=="
+    },
     "@types/glob": {
       "version": "7.1.3",
       "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz",
@@ -906,6 +1004,139 @@
       "integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==",
       "dev": true
     },
+    "@visx/annotation": {
+      "version": "1.18.1",
+      "resolved": "https://registry.npmjs.org/@visx/annotation/-/annotation-1.18.1.tgz",
+      "integrity": "sha512-z6zCk6PKmmeFziKKMBhJqJG4utg3dDWOCBZdR70HWSt9rl5cTMwIfATCuhJNbE2KuW6+QvTLiMCONySFwuVR+g==",
+      "requires": {
+        "@types/react": "*",
+        "@visx/drag": "1.18.1",
+        "@visx/group": "1.17.1",
+        "@visx/point": "1.7.0",
+        "@visx/shape": "1.17.1",
+        "@visx/text": "1.17.1",
+        "classnames": "^2.3.1",
+        "prop-types": "^15.5.10",
+        "react-use-measure": "^2.0.4"
+      },
+      "dependencies": {
+        "@types/d3-scale": {
+          "version": "3.3.2",
+          "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-3.3.2.tgz",
+          "integrity": "sha512-gGqr7x1ost9px3FvIfUMi5XA/F/yAf4UkUDtdQhpH92XCT0Oa7zkkRzY61gPVJq+DxpHn/btouw5ohWkbBsCzQ==",
+          "requires": {
+            "@types/d3-time": "^2"
+          }
+        },
+        "@types/d3-time": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-2.1.1.tgz",
+          "integrity": "sha512-9MVYlmIgmRR31C5b4FVSWtuMmBHh2mOWQYfl7XAYOa8dsnb7iEmUmRSWSFgXFtkjxO65d7hTUHQC+RhR/9IWFg=="
+        },
+        "@visx/curve": {
+          "version": "1.7.0",
+          "resolved": "https://registry.npmjs.org/@visx/curve/-/curve-1.7.0.tgz",
+          "integrity": "sha512-n0/SHM4YXjke+aEinhHFZPLMxWu3jbqtvqzfGJyibX8OmbDjavk9P+MHfGokUcw0xHy6Ch3YTuwbYuvVw5ny9A==",
+          "requires": {
+            "@types/d3-shape": "^1.3.1",
+            "d3-shape": "^1.0.6"
+          }
+        },
+        "@visx/group": {
+          "version": "1.17.1",
+          "resolved": "https://registry.npmjs.org/@visx/group/-/group-1.17.1.tgz",
+          "integrity": "sha512-g8pSqy8TXAisiOzypnVycDynEGlBhfxtVlwDmsbYB+XSFGEjnOheQSDohDI+ia7ek54Mw9uYe05tx5kP1hRMYw==",
+          "requires": {
+            "@types/react": "*",
+            "classnames": "^2.3.1",
+            "prop-types": "^15.6.2"
+          }
+        },
+        "@visx/point": {
+          "version": "1.7.0",
+          "resolved": "https://registry.npmjs.org/@visx/point/-/point-1.7.0.tgz",
+          "integrity": "sha512-oaoY/HXYHhmpkkeKI4rBPmFtjHWtxSrIhZCVm1ipPoyQp3voJ8L6JD5eUIVmmaUCdUGUGwL1lFLnJiQ2p1Vlwg=="
+        },
+        "@visx/scale": {
+          "version": "1.14.0",
+          "resolved": "https://registry.npmjs.org/@visx/scale/-/scale-1.14.0.tgz",
+          "integrity": "sha512-ovbtEOF/d76uGMJ5UZlxdS3t2T8I6md+aIwOXBaq0HdjaCLbe7HLlMyHJKjak/sqBxLAiCGVnechTUpSkfgSQw==",
+          "requires": {
+            "@types/d3-interpolate": "^1.3.1",
+            "@types/d3-scale": "^3.3.0",
+            "@types/d3-time": "^2.0.0",
+            "d3-interpolate": "^1.4.0",
+            "d3-scale": "^3.3.0",
+            "d3-time": "^2.1.1"
+          }
+        },
+        "@visx/shape": {
+          "version": "1.17.1",
+          "resolved": "https://registry.npmjs.org/@visx/shape/-/shape-1.17.1.tgz",
+          "integrity": "sha512-rVYFpytPCnV4s5U0za+jQ2jqFzKnmB3c8RP6fuOfF6kKosFPJcOYg9ikvewojARyMBTr1u3XvWV960Da+xyUdQ==",
+          "requires": {
+            "@types/d3-path": "^1.0.8",
+            "@types/d3-shape": "^1.3.1",
+            "@types/lodash": "^4.14.146",
+            "@types/react": "*",
+            "@visx/curve": "1.7.0",
+            "@visx/group": "1.17.1",
+            "@visx/scale": "1.14.0",
+            "classnames": "^2.3.1",
+            "d3-path": "^1.0.5",
+            "d3-shape": "^1.2.0",
+            "lodash": "^4.17.15",
+            "prop-types": "^15.5.10"
+          }
+        },
+        "@visx/text": {
+          "version": "1.17.1",
+          "resolved": "https://registry.npmjs.org/@visx/text/-/text-1.17.1.tgz",
+          "integrity": "sha512-Cx6iH0kVq3YqCfFj7U6bMiKwa/bz4Z3q0vPdxmnVGcPjGZM1ac/y61KFH263e164LJ5jFaTYpPrrFmbZoy8+Vg==",
+          "requires": {
+            "@types/lodash": "^4.14.160",
+            "@types/react": "*",
+            "classnames": "^2.3.1",
+            "lodash": "^4.17.20",
+            "prop-types": "^15.7.2",
+            "reduce-css-calc": "^1.3.0"
+          }
+        },
+        "classnames": {
+          "version": "2.3.1",
+          "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz",
+          "integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA=="
+        },
+        "d3-scale": {
+          "version": "3.3.0",
+          "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-3.3.0.tgz",
+          "integrity": "sha512-1JGp44NQCt5d1g+Yy+GeOnZP7xHo0ii8zsQp6PGzd+C1/dl0KGsp9A7Mxwp+1D1o4unbTTxVdU/ZOIEBoeZPbQ==",
+          "requires": {
+            "d3-array": "^2.3.0",
+            "d3-format": "1 - 2",
+            "d3-interpolate": "1.2.0 - 2",
+            "d3-time": "^2.1.1",
+            "d3-time-format": "2 - 3"
+          }
+        },
+        "d3-time": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-2.1.1.tgz",
+          "integrity": "sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ==",
+          "requires": {
+            "d3-array": "2"
+          }
+        },
+        "react-use-measure": {
+          "version": "2.0.4",
+          "resolved": "https://registry.npmjs.org/react-use-measure/-/react-use-measure-2.0.4.tgz",
+          "integrity": "sha512-7K2HIGaPMl3Q9ZQiEVjen3tRXl4UDda8LiTPy/QxP8dP2rl5gPBhf7mMH6MVjjRNv3loU7sNzey/ycPNnHVTxQ==",
+          "requires": {
+            "debounce": "^1.2.0"
+          }
+        }
+      }
+    },
     "@visx/axis": {
       "version": "1.6.1",
       "resolved": "https://registry.npmjs.org/@visx/axis/-/axis-1.6.1.tgz",
@@ -1001,6 +1232,32 @@
         "d3-shape": "^1.0.6"
       }
     },
+    "@visx/drag": {
+      "version": "1.18.1",
+      "resolved": "https://registry.npmjs.org/@visx/drag/-/drag-1.18.1.tgz",
+      "integrity": "sha512-5xsgUUthG/0Nq51HFWYIe3NaHT5csxuVqx/+VfNsjkGgCHntWkcS2soPlEMh4wUT2iPKRs9z9VtRAyrpN4TtKw==",
+      "requires": {
+        "@types/react": "*",
+        "@visx/event": "1.7.0",
+        "prop-types": "^15.5.10"
+      },
+      "dependencies": {
+        "@visx/event": {
+          "version": "1.7.0",
+          "resolved": "https://registry.npmjs.org/@visx/event/-/event-1.7.0.tgz",
+          "integrity": "sha512-RbAoKxvy+ildX2dVXC9/ZX94lQXPwjKgtO9jy7COc15knG4zmzsMCDYDC3uLd0+jE2o/+gSaZ/9r52p6zG5+IQ==",
+          "requires": {
+            "@types/react": "*",
+            "@visx/point": "1.7.0"
+          }
+        },
+        "@visx/point": {
+          "version": "1.7.0",
+          "resolved": "https://registry.npmjs.org/@visx/point/-/point-1.7.0.tgz",
+          "integrity": "sha512-oaoY/HXYHhmpkkeKI4rBPmFtjHWtxSrIhZCVm1ipPoyQp3voJ8L6JD5eUIVmmaUCdUGUGwL1lFLnJiQ2p1Vlwg=="
+        }
+      }
+    },
     "@visx/event": {
       "version": "1.3.0",
       "resolved": "https://registry.npmjs.org/@visx/event/-/event-1.3.0.tgz",
@@ -1010,6 +1267,36 @@
         "@visx/point": "1.0.0"
       }
     },
+    "@visx/glyph": {
+      "version": "1.17.1",
+      "resolved": "https://registry.npmjs.org/@visx/glyph/-/glyph-1.17.1.tgz",
+      "integrity": "sha512-9KAPmO7DsH1Iq+2kZs8oTgirgYWRq7EacNyEtsq78uuHqw0gFqmOuyYV6+iHelLbulNCAzHKVAZ7Aebfy7G8ZA==",
+      "requires": {
+        "@types/d3-shape": "^1.3.1",
+        "@types/react": "*",
+        "@visx/group": "1.17.1",
+        "classnames": "^2.3.1",
+        "d3-shape": "^1.2.0",
+        "prop-types": "^15.6.2"
+      },
+      "dependencies": {
+        "@visx/group": {
+          "version": "1.17.1",
+          "resolved": "https://registry.npmjs.org/@visx/group/-/group-1.17.1.tgz",
+          "integrity": "sha512-g8pSqy8TXAisiOzypnVycDynEGlBhfxtVlwDmsbYB+XSFGEjnOheQSDohDI+ia7ek54Mw9uYe05tx5kP1hRMYw==",
+          "requires": {
+            "@types/react": "*",
+            "classnames": "^2.3.1",
+            "prop-types": "^15.6.2"
+          }
+        },
+        "classnames": {
+          "version": "2.3.1",
+          "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz",
+          "integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA=="
+        }
+      }
+    },
     "@visx/gradient": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/@visx/gradient/-/gradient-1.0.0.tgz",
@@ -1059,6 +1346,159 @@
       "resolved": "https://registry.npmjs.org/@visx/point/-/point-1.0.0.tgz",
       "integrity": "sha512-0L3ILwv6ro0DsQVbA1lo8fo6q3wvIeSTt9C8NarUUkoTNSFZaJtlmvwg2238r8fwwmSv0v9QFBj1hBz4o0bHrg=="
     },
+    "@visx/react-spring": {
+      "version": "1.17.1",
+      "resolved": "https://registry.npmjs.org/@visx/react-spring/-/react-spring-1.17.1.tgz",
+      "integrity": "sha512-U2+cXYpmuwN8/TNNJAiqAcXHPewKbb2vT+YmDmkIk9G20INO95EKJbHE5+homf+Jg7mRr5En31Orxjt6eIKgzA==",
+      "requires": {
+        "@types/react": "*",
+        "@visx/axis": "1.17.1",
+        "@visx/grid": "1.17.1",
+        "@visx/scale": "1.14.0",
+        "@visx/text": "1.17.1",
+        "classnames": "^2.3.1",
+        "prop-types": "^15.6.2"
+      },
+      "dependencies": {
+        "@types/d3-scale": {
+          "version": "3.3.2",
+          "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-3.3.2.tgz",
+          "integrity": "sha512-gGqr7x1ost9px3FvIfUMi5XA/F/yAf4UkUDtdQhpH92XCT0Oa7zkkRzY61gPVJq+DxpHn/btouw5ohWkbBsCzQ==",
+          "requires": {
+            "@types/d3-time": "^2"
+          }
+        },
+        "@types/d3-time": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-2.1.1.tgz",
+          "integrity": "sha512-9MVYlmIgmRR31C5b4FVSWtuMmBHh2mOWQYfl7XAYOa8dsnb7iEmUmRSWSFgXFtkjxO65d7hTUHQC+RhR/9IWFg=="
+        },
+        "@visx/axis": {
+          "version": "1.17.1",
+          "resolved": "https://registry.npmjs.org/@visx/axis/-/axis-1.17.1.tgz",
+          "integrity": "sha512-3JdAY8xwA4xVnzkbXdIzCOWYCknCgw3L185lOJTXWNGO7kIgzbQ2YrLXnet37BFgD83MfxmlP6LhiHLkKVI6OQ==",
+          "requires": {
+            "@types/react": "*",
+            "@visx/group": "1.17.1",
+            "@visx/point": "1.7.0",
+            "@visx/scale": "1.14.0",
+            "@visx/shape": "1.17.1",
+            "@visx/text": "1.17.1",
+            "classnames": "^2.3.1",
+            "prop-types": "^15.6.0"
+          }
+        },
+        "@visx/curve": {
+          "version": "1.7.0",
+          "resolved": "https://registry.npmjs.org/@visx/curve/-/curve-1.7.0.tgz",
+          "integrity": "sha512-n0/SHM4YXjke+aEinhHFZPLMxWu3jbqtvqzfGJyibX8OmbDjavk9P+MHfGokUcw0xHy6Ch3YTuwbYuvVw5ny9A==",
+          "requires": {
+            "@types/d3-shape": "^1.3.1",
+            "d3-shape": "^1.0.6"
+          }
+        },
+        "@visx/grid": {
+          "version": "1.17.1",
+          "resolved": "https://registry.npmjs.org/@visx/grid/-/grid-1.17.1.tgz",
+          "integrity": "sha512-dse9q3weDqPNmeXK0lGKKPRgGiDuUjJ7Mt7NNonPUyXPctNmv6lJEWZu9HJrXEGiCAVNa8PHJ7Qkns/z+mH88Q==",
+          "requires": {
+            "@types/react": "*",
+            "@visx/curve": "1.7.0",
+            "@visx/group": "1.17.1",
+            "@visx/point": "1.7.0",
+            "@visx/scale": "1.14.0",
+            "@visx/shape": "1.17.1",
+            "classnames": "^2.3.1",
+            "prop-types": "^15.6.2"
+          }
+        },
+        "@visx/group": {
+          "version": "1.17.1",
+          "resolved": "https://registry.npmjs.org/@visx/group/-/group-1.17.1.tgz",
+          "integrity": "sha512-g8pSqy8TXAisiOzypnVycDynEGlBhfxtVlwDmsbYB+XSFGEjnOheQSDohDI+ia7ek54Mw9uYe05tx5kP1hRMYw==",
+          "requires": {
+            "@types/react": "*",
+            "classnames": "^2.3.1",
+            "prop-types": "^15.6.2"
+          }
+        },
+        "@visx/point": {
+          "version": "1.7.0",
+          "resolved": "https://registry.npmjs.org/@visx/point/-/point-1.7.0.tgz",
+          "integrity": "sha512-oaoY/HXYHhmpkkeKI4rBPmFtjHWtxSrIhZCVm1ipPoyQp3voJ8L6JD5eUIVmmaUCdUGUGwL1lFLnJiQ2p1Vlwg=="
+        },
+        "@visx/scale": {
+          "version": "1.14.0",
+          "resolved": "https://registry.npmjs.org/@visx/scale/-/scale-1.14.0.tgz",
+          "integrity": "sha512-ovbtEOF/d76uGMJ5UZlxdS3t2T8I6md+aIwOXBaq0HdjaCLbe7HLlMyHJKjak/sqBxLAiCGVnechTUpSkfgSQw==",
+          "requires": {
+            "@types/d3-interpolate": "^1.3.1",
+            "@types/d3-scale": "^3.3.0",
+            "@types/d3-time": "^2.0.0",
+            "d3-interpolate": "^1.4.0",
+            "d3-scale": "^3.3.0",
+            "d3-time": "^2.1.1"
+          }
+        },
+        "@visx/shape": {
+          "version": "1.17.1",
+          "resolved": "https://registry.npmjs.org/@visx/shape/-/shape-1.17.1.tgz",
+          "integrity": "sha512-rVYFpytPCnV4s5U0za+jQ2jqFzKnmB3c8RP6fuOfF6kKosFPJcOYg9ikvewojARyMBTr1u3XvWV960Da+xyUdQ==",
+          "requires": {
+            "@types/d3-path": "^1.0.8",
+            "@types/d3-shape": "^1.3.1",
+            "@types/lodash": "^4.14.146",
+            "@types/react": "*",
+            "@visx/curve": "1.7.0",
+            "@visx/group": "1.17.1",
+            "@visx/scale": "1.14.0",
+            "classnames": "^2.3.1",
+            "d3-path": "^1.0.5",
+            "d3-shape": "^1.2.0",
+            "lodash": "^4.17.15",
+            "prop-types": "^15.5.10"
+          }
+        },
+        "@visx/text": {
+          "version": "1.17.1",
+          "resolved": "https://registry.npmjs.org/@visx/text/-/text-1.17.1.tgz",
+          "integrity": "sha512-Cx6iH0kVq3YqCfFj7U6bMiKwa/bz4Z3q0vPdxmnVGcPjGZM1ac/y61KFH263e164LJ5jFaTYpPrrFmbZoy8+Vg==",
+          "requires": {
+            "@types/lodash": "^4.14.160",
+            "@types/react": "*",
+            "classnames": "^2.3.1",
+            "lodash": "^4.17.20",
+            "prop-types": "^15.7.2",
+            "reduce-css-calc": "^1.3.0"
+          }
+        },
+        "classnames": {
+          "version": "2.3.1",
+          "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz",
+          "integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA=="
+        },
+        "d3-scale": {
+          "version": "3.3.0",
+          "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-3.3.0.tgz",
+          "integrity": "sha512-1JGp44NQCt5d1g+Yy+GeOnZP7xHo0ii8zsQp6PGzd+C1/dl0KGsp9A7Mxwp+1D1o4unbTTxVdU/ZOIEBoeZPbQ==",
+          "requires": {
+            "d3-array": "^2.3.0",
+            "d3-format": "1 - 2",
+            "d3-interpolate": "1.2.0 - 2",
+            "d3-time": "^2.1.1",
+            "d3-time-format": "2 - 3"
+          }
+        },
+        "d3-time": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-2.1.1.tgz",
+          "integrity": "sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ==",
+          "requires": {
+            "d3-array": "2"
+          }
+        }
+      }
+    },
     "@visx/responsive": {
       "version": "1.3.0",
       "resolved": "https://registry.npmjs.org/@visx/responsive/-/responsive-1.3.0.tgz",
@@ -1131,6 +1571,271 @@
         "react-use-measure": "2.0.1"
       }
     },
+    "@visx/voronoi": {
+      "version": "1.17.1",
+      "resolved": "https://registry.npmjs.org/@visx/voronoi/-/voronoi-1.17.1.tgz",
+      "integrity": "sha512-XpgQ5siRYI9Vvw+Q82avIntDzfkSrIT3EmN2J/L/6ZnT3nTCjWksTEgQQ3G9GqoX510srbX8wL+mRqkYP+3O4Q==",
+      "requires": {
+        "@types/d3-voronoi": "^1.1.9",
+        "@types/react": "*",
+        "classnames": "^2.3.1",
+        "d3-voronoi": "^1.1.2",
+        "prop-types": "^15.6.1"
+      },
+      "dependencies": {
+        "classnames": {
+          "version": "2.3.1",
+          "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz",
+          "integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA=="
+        }
+      }
+    },
+    "@visx/xychart": {
+      "version": "1.18.1",
+      "resolved": "https://registry.npmjs.org/@visx/xychart/-/xychart-1.18.1.tgz",
+      "integrity": "sha512-VyC7yBpLUSgzLZIWWRtf1pCP0xuYLjHEwAXl2LdCSrnyUs2pMTms7xMUNbq8uwR4e8bbBY5dbsRg/7X95tB8Yg==",
+      "requires": {
+        "@types/lodash": "^4.14.146",
+        "@types/react": "*",
+        "@visx/annotation": "1.18.1",
+        "@visx/axis": "1.17.1",
+        "@visx/event": "1.7.0",
+        "@visx/glyph": "1.17.1",
+        "@visx/grid": "1.17.1",
+        "@visx/react-spring": "1.17.1",
+        "@visx/responsive": "1.10.1",
+        "@visx/scale": "1.14.0",
+        "@visx/shape": "1.17.1",
+        "@visx/text": "1.17.1",
+        "@visx/tooltip": "1.17.1",
+        "@visx/voronoi": "1.17.1",
+        "classnames": "^2.3.1",
+        "d3-array": "^2.6.0",
+        "d3-interpolate-path": "2.2.1",
+        "d3-shape": "^2.0.0",
+        "lodash": "^4.17.10",
+        "mitt": "^2.1.0",
+        "prop-types": "^15.6.2"
+      },
+      "dependencies": {
+        "@types/d3-scale": {
+          "version": "3.3.2",
+          "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-3.3.2.tgz",
+          "integrity": "sha512-gGqr7x1ost9px3FvIfUMi5XA/F/yAf4UkUDtdQhpH92XCT0Oa7zkkRzY61gPVJq+DxpHn/btouw5ohWkbBsCzQ==",
+          "requires": {
+            "@types/d3-time": "^2"
+          }
+        },
+        "@types/d3-time": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-2.1.1.tgz",
+          "integrity": "sha512-9MVYlmIgmRR31C5b4FVSWtuMmBHh2mOWQYfl7XAYOa8dsnb7iEmUmRSWSFgXFtkjxO65d7hTUHQC+RhR/9IWFg=="
+        },
+        "@visx/axis": {
+          "version": "1.17.1",
+          "resolved": "https://registry.npmjs.org/@visx/axis/-/axis-1.17.1.tgz",
+          "integrity": "sha512-3JdAY8xwA4xVnzkbXdIzCOWYCknCgw3L185lOJTXWNGO7kIgzbQ2YrLXnet37BFgD83MfxmlP6LhiHLkKVI6OQ==",
+          "requires": {
+            "@types/react": "*",
+            "@visx/group": "1.17.1",
+            "@visx/point": "1.7.0",
+            "@visx/scale": "1.14.0",
+            "@visx/shape": "1.17.1",
+            "@visx/text": "1.17.1",
+            "classnames": "^2.3.1",
+            "prop-types": "^15.6.0"
+          }
+        },
+        "@visx/bounds": {
+          "version": "1.7.0",
+          "resolved": "https://registry.npmjs.org/@visx/bounds/-/bounds-1.7.0.tgz",
+          "integrity": "sha512-ajF6PTgDoZTfwv5J0ZTx1miXY8lk3sGhMVqE3UsMubdTZBlOgeZMT4OmtTPtbCJTBTgw0FD0gd7X3gZ+3X9HgQ==",
+          "requires": {
+            "@types/react": "*",
+            "@types/react-dom": "*",
+            "prop-types": "^15.5.10"
+          }
+        },
+        "@visx/curve": {
+          "version": "1.7.0",
+          "resolved": "https://registry.npmjs.org/@visx/curve/-/curve-1.7.0.tgz",
+          "integrity": "sha512-n0/SHM4YXjke+aEinhHFZPLMxWu3jbqtvqzfGJyibX8OmbDjavk9P+MHfGokUcw0xHy6Ch3YTuwbYuvVw5ny9A==",
+          "requires": {
+            "@types/d3-shape": "^1.3.1",
+            "d3-shape": "^1.0.6"
+          },
+          "dependencies": {
+            "d3-shape": {
+              "version": "1.3.7",
+              "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz",
+              "integrity": "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==",
+              "requires": {
+                "d3-path": "1"
+              }
+            }
+          }
+        },
+        "@visx/event": {
+          "version": "1.7.0",
+          "resolved": "https://registry.npmjs.org/@visx/event/-/event-1.7.0.tgz",
+          "integrity": "sha512-RbAoKxvy+ildX2dVXC9/ZX94lQXPwjKgtO9jy7COc15knG4zmzsMCDYDC3uLd0+jE2o/+gSaZ/9r52p6zG5+IQ==",
+          "requires": {
+            "@types/react": "*",
+            "@visx/point": "1.7.0"
+          }
+        },
+        "@visx/grid": {
+          "version": "1.17.1",
+          "resolved": "https://registry.npmjs.org/@visx/grid/-/grid-1.17.1.tgz",
+          "integrity": "sha512-dse9q3weDqPNmeXK0lGKKPRgGiDuUjJ7Mt7NNonPUyXPctNmv6lJEWZu9HJrXEGiCAVNa8PHJ7Qkns/z+mH88Q==",
+          "requires": {
+            "@types/react": "*",
+            "@visx/curve": "1.7.0",
+            "@visx/group": "1.17.1",
+            "@visx/point": "1.7.0",
+            "@visx/scale": "1.14.0",
+            "@visx/shape": "1.17.1",
+            "classnames": "^2.3.1",
+            "prop-types": "^15.6.2"
+          }
+        },
+        "@visx/group": {
+          "version": "1.17.1",
+          "resolved": "https://registry.npmjs.org/@visx/group/-/group-1.17.1.tgz",
+          "integrity": "sha512-g8pSqy8TXAisiOzypnVycDynEGlBhfxtVlwDmsbYB+XSFGEjnOheQSDohDI+ia7ek54Mw9uYe05tx5kP1hRMYw==",
+          "requires": {
+            "@types/react": "*",
+            "classnames": "^2.3.1",
+            "prop-types": "^15.6.2"
+          }
+        },
+        "@visx/point": {
+          "version": "1.7.0",
+          "resolved": "https://registry.npmjs.org/@visx/point/-/point-1.7.0.tgz",
+          "integrity": "sha512-oaoY/HXYHhmpkkeKI4rBPmFtjHWtxSrIhZCVm1ipPoyQp3voJ8L6JD5eUIVmmaUCdUGUGwL1lFLnJiQ2p1Vlwg=="
+        },
+        "@visx/responsive": {
+          "version": "1.10.1",
+          "resolved": "https://registry.npmjs.org/@visx/responsive/-/responsive-1.10.1.tgz",
+          "integrity": "sha512-7FT2BBmWFkFFqynI9C1NYfVOKT1FsNOm6MwWMqXKA7TMomdBW0wdtQNB1bHvwJvWurM/sNqxcQ/CBED6t9xujQ==",
+          "requires": {
+            "@types/lodash": "^4.14.146",
+            "@types/react": "*",
+            "lodash": "^4.17.10",
+            "prop-types": "^15.6.1",
+            "resize-observer-polyfill": "1.5.1"
+          }
+        },
+        "@visx/scale": {
+          "version": "1.14.0",
+          "resolved": "https://registry.npmjs.org/@visx/scale/-/scale-1.14.0.tgz",
+          "integrity": "sha512-ovbtEOF/d76uGMJ5UZlxdS3t2T8I6md+aIwOXBaq0HdjaCLbe7HLlMyHJKjak/sqBxLAiCGVnechTUpSkfgSQw==",
+          "requires": {
+            "@types/d3-interpolate": "^1.3.1",
+            "@types/d3-scale": "^3.3.0",
+            "@types/d3-time": "^2.0.0",
+            "d3-interpolate": "^1.4.0",
+            "d3-scale": "^3.3.0",
+            "d3-time": "^2.1.1"
+          }
+        },
+        "@visx/shape": {
+          "version": "1.17.1",
+          "resolved": "https://registry.npmjs.org/@visx/shape/-/shape-1.17.1.tgz",
+          "integrity": "sha512-rVYFpytPCnV4s5U0za+jQ2jqFzKnmB3c8RP6fuOfF6kKosFPJcOYg9ikvewojARyMBTr1u3XvWV960Da+xyUdQ==",
+          "requires": {
+            "@types/d3-path": "^1.0.8",
+            "@types/d3-shape": "^1.3.1",
+            "@types/lodash": "^4.14.146",
+            "@types/react": "*",
+            "@visx/curve": "1.7.0",
+            "@visx/group": "1.17.1",
+            "@visx/scale": "1.14.0",
+            "classnames": "^2.3.1",
+            "d3-path": "^1.0.5",
+            "d3-shape": "^1.2.0",
+            "lodash": "^4.17.15",
+            "prop-types": "^15.5.10"
+          },
+          "dependencies": {
+            "d3-shape": {
+              "version": "1.3.7",
+              "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz",
+              "integrity": "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==",
+              "requires": {
+                "d3-path": "1"
+              }
+            }
+          }
+        },
+        "@visx/text": {
+          "version": "1.17.1",
+          "resolved": "https://registry.npmjs.org/@visx/text/-/text-1.17.1.tgz",
+          "integrity": "sha512-Cx6iH0kVq3YqCfFj7U6bMiKwa/bz4Z3q0vPdxmnVGcPjGZM1ac/y61KFH263e164LJ5jFaTYpPrrFmbZoy8+Vg==",
+          "requires": {
+            "@types/lodash": "^4.14.160",
+            "@types/react": "*",
+            "classnames": "^2.3.1",
+            "lodash": "^4.17.20",
+            "prop-types": "^15.7.2",
+            "reduce-css-calc": "^1.3.0"
+          }
+        },
+        "@visx/tooltip": {
+          "version": "1.17.1",
+          "resolved": "https://registry.npmjs.org/@visx/tooltip/-/tooltip-1.17.1.tgz",
+          "integrity": "sha512-YfRgVtKSLTn3iW8CT5+CfTWhSXGeAp01SaPDThtdaUTx89rKv5wb4oyVgeQ5g2ScRYVC8mYj5RzY/pj3RrezFQ==",
+          "requires": {
+            "@types/react": "*",
+            "@visx/bounds": "1.7.0",
+            "classnames": "^2.3.1",
+            "prop-types": "^15.5.10",
+            "react-use-measure": "^2.0.4"
+          }
+        },
+        "classnames": {
+          "version": "2.3.1",
+          "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz",
+          "integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA=="
+        },
+        "d3-scale": {
+          "version": "3.3.0",
+          "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-3.3.0.tgz",
+          "integrity": "sha512-1JGp44NQCt5d1g+Yy+GeOnZP7xHo0ii8zsQp6PGzd+C1/dl0KGsp9A7Mxwp+1D1o4unbTTxVdU/ZOIEBoeZPbQ==",
+          "requires": {
+            "d3-array": "^2.3.0",
+            "d3-format": "1 - 2",
+            "d3-interpolate": "1.2.0 - 2",
+            "d3-time": "^2.1.1",
+            "d3-time-format": "2 - 3"
+          }
+        },
+        "d3-shape": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-2.1.0.tgz",
+          "integrity": "sha512-PnjUqfM2PpskbSLTJvAzp2Wv4CZsnAgTfcVRTwW03QR3MkXF8Uo7B1y/lWkAsmbKwuecto++4NlsYcvYpXpTHA==",
+          "requires": {
+            "d3-path": "1 - 2"
+          }
+        },
+        "d3-time": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-2.1.1.tgz",
+          "integrity": "sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ==",
+          "requires": {
+            "d3-array": "2"
+          }
+        },
+        "react-use-measure": {
+          "version": "2.0.4",
+          "resolved": "https://registry.npmjs.org/react-use-measure/-/react-use-measure-2.0.4.tgz",
+          "integrity": "sha512-7K2HIGaPMl3Q9ZQiEVjen3tRXl4UDda8LiTPy/QxP8dP2rl5gPBhf7mMH6MVjjRNv3loU7sNzey/ycPNnHVTxQ==",
+          "requires": {
+            "debounce": "^1.2.0"
+          }
+        }
+      }
+    },
     "@webassemblyjs/ast": {
       "version": "1.9.0",
       "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz",
@@ -2582,6 +3287,11 @@
         "d3-color": "1"
       }
     },
+    "d3-interpolate-path": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/d3-interpolate-path/-/d3-interpolate-path-2.2.1.tgz",
+      "integrity": "sha512-6qLLh/KJVzls0XtMsMpcxhqMhgVEN7VIbR/6YGZe2qlS8KDgyyVB20XcmGnDyB051HcefQXM/Tppa9vcANEA4Q=="
+    },
     "d3-path": {
       "version": "1.0.9",
       "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz",
@@ -2625,6 +3335,11 @@
         "d3-time": "1 - 2"
       }
     },
+    "d3-voronoi": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/d3-voronoi/-/d3-voronoi-1.1.4.tgz",
+      "integrity": "sha512-dArJ32hchFsrQ8uMiTBLq256MpnZjeuBtdHpaDlYuQyjU0CVzCJl/BVW+SkszaAeH95D/8gxqAhgx0ouAWAfRg=="
+    },
     "debounce": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.0.tgz",
@@ -5260,6 +5975,11 @@
         "through2": "^2.0.0"
       }
     },
+    "mitt": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/mitt/-/mitt-2.1.0.tgz",
+      "integrity": "sha512-ILj2TpLiysu2wkBbWjAmww7TkZb65aiQO+DkVdUTBpBXq+MHYiETENkKFMtsJZX1Lf4pe4QOrTSjIfUwN5lRdg=="
+    },
     "mixin-deep": {
       "version": "1.3.2",
       "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz",
@@ -6291,6 +7011,19 @@
         "tiny-warning": "^1.0.0"
       }
     },
+    "react-spring": {
+      "version": "9.2.4",
+      "resolved": "https://registry.npmjs.org/react-spring/-/react-spring-9.2.4.tgz",
+      "integrity": "sha512-bMjbyTW0ZGd+/h9cjtohLqCwOGqX2OuaTvalOVfLCGmhzEg/u3GgopI3LAm4UD2Br3MNdVdGgNVoESg4MGqKFQ==",
+      "requires": {
+        "@react-spring/core": "~9.2.0",
+        "@react-spring/konva": "~9.2.0",
+        "@react-spring/native": "~9.2.0",
+        "@react-spring/three": "~9.2.0",
+        "@react-spring/web": "~9.2.0",
+        "@react-spring/zdog": "~9.2.0"
+      }
+    },
     "react-table": {
       "version": "7.7.0",
       "resolved": "https://registry.npmjs.org/react-table/-/react-table-7.7.0.tgz",

+ 2 - 0
dashboard/package.json

@@ -22,6 +22,7 @@
     "@visx/scale": "^1.4.0",
     "@visx/shape": "^1.4.0",
     "@visx/tooltip": "^1.3.0",
+    "@visx/xychart": "^1.18.1",
     "ace-builds": "^1.4.12",
     "anser": "^2.0.1",
     "axios": "^0.20.0",
@@ -43,6 +44,7 @@
     "react-dom": "^16.13.1",
     "react-modal": "^3.11.2",
     "react-router-dom": "^5.2.0",
+    "react-spring": "^9.2.4",
     "react-table": "^7.7.0",
     "semver": "^7.3.5",
     "styled-components": "^5.2.0"

+ 1 - 1
dashboard/src/main/home/cluster-dashboard/expanded-chart/ExpandedChart.tsx

@@ -415,7 +415,7 @@ const ExpandedChart: React.FC<Props> = (props) => {
   const updateTabs = () => {
     // Collate non-form tabs
     let tabOptions = [] as any[];
-    tabOptions.push({ label: "Status", value: "status" });
+    // tabOptions.push({ label: "Status", value: "status" });
 
     if (props.isMetricsInstalled) {
       tabOptions.push({ label: "Metrics", value: "metrics" });

+ 106 - 43
dashboard/src/main/home/cluster-dashboard/expanded-chart/metrics/AreaChart.tsx

@@ -1,4 +1,4 @@
-import React, { useMemo, useCallback } from "react";
+import React, { useMemo, useCallback, useRef } from "react";
 import { AreaClosed, Line, Bar, LinePath } from "@visx/shape";
 import { curveMonotoneX } from "@visx/curve";
 import { scaleTime, scaleLinear } from "@visx/scale";
@@ -55,7 +55,7 @@ const formats: { [range: string]: (date: Date) => string } = {
 
 // accessors
 const getDate = (d: NormalizedMetricsData) => new Date(d.date * 1000);
-const getValue = (d: NormalizedMetricsData) => d.value;
+const getValue = (d: NormalizedMetricsData) => d?.value;
 
 const bisectDate = bisector<NormalizedMetricsData, Date>(
   (d) => new Date(d.date * 1000)
@@ -63,7 +63,9 @@ const bisectDate = bisector<NormalizedMetricsData, Date>(
 
 export type AreaProps = {
   data: NormalizedMetricsData[];
-  hpaData: NormalizedMetricsData[];
+  dataKey: string;
+  hpaEnabled?: boolean;
+  hpaData?: NormalizedMetricsData[];
   resolution: string;
   width: number;
   height: number;
@@ -74,7 +76,8 @@ export type AreaProps = {
 
 const AreaChart: React.FunctionComponent<AreaProps> = ({
   data,
-  hpaData,
+  hpaEnabled = false,
+  hpaData = [],
   resolution,
   width,
   height,
@@ -88,8 +91,12 @@ const AreaChart: React.FunctionComponent<AreaProps> = ({
     tooltipData,
     tooltipTop,
     tooltipLeft,
-  } = useTooltip<NormalizedMetricsData>();
+  } = useTooltip<{
+    data: NormalizedMetricsData;
+    tooltipHpaData: NormalizedMetricsData;
+  }>();
 
+  const svgContainer = useRef();
   // bounds
   const innerWidth = width - margin.left - margin.right - 40;
   const innerHeight = height - margin.top - margin.bottom - 20;
@@ -101,7 +108,7 @@ const AreaChart: React.FunctionComponent<AreaProps> = ({
         range: [margin.left, innerWidth + margin.left],
         domain: extent([...globalData, ...hpaData], getDate) as [Date, Date],
       }),
-    [innerWidth, margin.left, width, height, data, hpaData]
+    [margin.left, width, height, data, hpaData]
   );
   const valueScale = useMemo(
     () =>
@@ -110,31 +117,19 @@ const AreaChart: React.FunctionComponent<AreaProps> = ({
         domain: [0, 1.25 * max([...globalData, ...hpaData], getValue)],
         nice: true,
       }),
-    [margin.top, innerHeight, width, height, data, hpaData]
+    [margin.top, width, height, data, hpaData]
   );
 
-  const xScale = useMemo(
-    () =>
-      scaleTime({
-        domain: extent(hpaData, getDate) as number[],
-        range: [0, width],
-      }),
-    [width, hpaData]
-  );
-  const yScale = useMemo(() => {
-    return scaleLinear({
-      domain: extent(hpaData, getValue) as number[],
-      range: [innerHeight + margin.top, margin.top],
-    });
-  }, [margin.top, innerHeight, width, height, hpaData]);
-
   // tooltip handler
   const handleTooltip = useCallback(
     (
       event: React.TouchEvent<SVGRectElement> | React.MouseEvent<SVGRectElement>
     ) => {
+      const isHpaEnabled = hpaEnabled && !!hpaData.length;
+
       const { x } = localPoint(event) || { x: 0 };
       const x0 = dateScale.invert(x);
+
       const index = bisectDate(globalData, x0, 1);
       const d0 = globalData[index - 1];
       const d1 = globalData[index];
@@ -148,22 +143,71 @@ const AreaChart: React.FunctionComponent<AreaProps> = ({
             : d0;
       }
 
+      if (!isHpaEnabled) {
+        showTooltip({
+          tooltipData: { data: d, tooltipHpaData: undefined },
+          tooltipLeft: x || 0,
+          tooltipTop: valueScale(getValue(d)) || 0,
+        });
+        return;
+      }
+
+      const tooltipHpaData0 = hpaData[index - 1];
+      const tooltipHpaData1 = hpaData[index];
+      let tooltipHpaData = tooltipHpaData0;
+
+      if (tooltipHpaData1 && getDate(tooltipHpaData1)) {
+        tooltipHpaData =
+          x0.valueOf() - getDate(tooltipHpaData0).valueOf() >
+          getDate(tooltipHpaData1).valueOf() - x0.valueOf()
+            ? tooltipHpaData1
+            : tooltipHpaData0;
+      }
+
+      const container: SVGSVGElement = svgContainer.current;
+
+      let point = container.createSVGPoint();
+      // @ts-ignore
+      point.x = (event as any)?.clientX || 0;
+      // @ts-ignore
+      point.y = (event as any)?.clientY || 0;
+      point = point?.matrixTransform(container.getScreenCTM().inverse());
+
       showTooltip({
-        tooltipData: d,
+        tooltipData: { data: d, tooltipHpaData },
         tooltipLeft: x || 0,
-        tooltipTop: valueScale(getValue(d)) || 0,
+        tooltipTop: point.y || 0,
       });
     },
-    [showTooltip, valueScale, dateScale, width, height, data, hpaData]
+    [
+      showTooltip,
+      valueScale,
+      dateScale,
+      width,
+      height,
+      data,
+      hpaData,
+      svgContainer,
+      hpaEnabled,
+    ]
   );
 
   if (width == 0 || height == 0 || width < 10) {
     return null;
   }
+  const hpaGraphTooltipGlyphPosition =
+    (hpaEnabled &&
+      tooltipData?.tooltipHpaData &&
+      valueScale(getValue(tooltipData?.tooltipHpaData))) ||
+    0;
+
+  const dataGraphTooltipGlyphPosition =
+    (tooltipData?.data && valueScale(getValue(tooltipData.data))) || 0;
 
+  const isHpaEnabled = hpaEnabled && !!hpaData.length;
   return (
     <div>
-      <svg width={width} height={height}>
+      <svg width={width} height={height} ref={svgContainer}>
         <rect
           x={0}
           y={0}
@@ -214,11 +258,14 @@ const AreaChart: React.FunctionComponent<AreaProps> = ({
           curve={curveMonotoneX}
         />
         <LinePath<NormalizedMetricsData>
-          stroke="#fd0101"
+          stroke="#ffffff"
           strokeWidth={2}
           data={hpaData}
           x={(d) => dateScale(getDate(d)) ?? 0}
           y={(d) => valueScale(getValue(d)) ?? 0}
+          strokeDasharray="6,4"
+          strokeOpacity={1}
+          pointerEvents="none"
         />
         <AxisLeft
           left={10}
@@ -270,7 +317,7 @@ const AreaChart: React.FunctionComponent<AreaProps> = ({
             />
             <circle
               cx={tooltipLeft}
-              cy={tooltipTop + 1}
+              cy={dataGraphTooltipGlyphPosition + 1}
               r={4}
               fill="black"
               fillOpacity={0.1}
@@ -281,13 +328,37 @@ const AreaChart: React.FunctionComponent<AreaProps> = ({
             />
             <circle
               cx={tooltipLeft}
-              cy={tooltipTop}
+              cy={dataGraphTooltipGlyphPosition}
               r={4}
               fill={accentColorDark}
               stroke="white"
               strokeWidth={2}
               pointerEvents="none"
             />
+            {isHpaEnabled && (
+              <>
+                <circle
+                  cx={tooltipLeft}
+                  cy={hpaGraphTooltipGlyphPosition + 1}
+                  r={4}
+                  fill="black"
+                  fillOpacity={0.1}
+                  stroke="black"
+                  strokeOpacity={0.1}
+                  strokeWidth={2}
+                  pointerEvents="none"
+                />
+                <circle
+                  cx={tooltipLeft}
+                  cy={hpaGraphTooltipGlyphPosition}
+                  r={4}
+                  fill={accentColorDark}
+                  stroke="white"
+                  strokeWidth={2}
+                  pointerEvents="none"
+                />
+              </>
+            )}
           </g>
         )}
       </svg>
@@ -297,31 +368,23 @@ const AreaChart: React.FunctionComponent<AreaProps> = ({
             key={Math.random()}
             top={tooltipTop - 12}
             left={tooltipLeft + 12}
-            style={tooltipStyles}
-          >
-            {getValue(tooltipData)}
-          </TooltipWithBounds>
-          <Tooltip
-            top={-10}
-            left={tooltipLeft}
             style={{
               ...defaultStyles,
               background: "#26272f",
               color: "#aaaabb",
-              width: 100,
-              paddingTop: 35,
               textAlign: "center",
-              transform: "translateX(-60px)",
             }}
           >
-            {formatDate(getDate(tooltipData))}
-          </Tooltip>
+            {formatDate(getDate(tooltipData.data))}
+            <div>CPU DATA: {getValue(tooltipData.data)}</div>
+            {isHpaEnabled && (
+              <div>HPA DATA: {getValue(tooltipData.tooltipHpaData)}</div>
+            )}
+          </TooltipWithBounds>
         </div>
       )}
     </div>
   );
 };
 
-const TooltipHelper = () => {};
-
 export default AreaChart;

+ 2 - 0
dashboard/src/main/home/cluster-dashboard/expanded-chart/metrics/MetricsSection.tsx

@@ -462,8 +462,10 @@ const MetricsSection: React.FunctionComponent<PropsType> = ({
         <ParentSize>
           {({ width, height }) => (
             <AreaChart
+              dataKey={selectedMetricLabel}
               data={data}
               hpaData={hpaData}
+              hpaEnabled={currentChart?.config?.autoscaling?.enabled}
               width={width}
               height={height - 10}
               resolution={selectedRange}