diff --git a/priv/frontend/package-lock.json b/priv/frontend/package-lock.json index 5d72e9e..9fb3637 100644 --- a/priv/frontend/package-lock.json +++ b/priv/frontend/package-lock.json @@ -1,6 +1,6 @@ { "name": "elstatus", - "version": "0.1.0", + "version": "0.0.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -34,48 +34,6 @@ "prop-types": "^15.5.10" } }, - "@nivo/core": { - "version": "0.42.1", - "resolved": "https://registry.npmjs.org/@nivo/core/-/core-0.42.1.tgz", - "integrity": "sha512-T3DgbV9x6snbHxNQ2vWZYJRCnI6iUqh9A6Kn1Fsy1L7Sn97fsf89e1qMp0CpILhyJu7Fj+VXRYtJwby0wH6GAA==", - "requires": { - "d3-color": "^1.0.3", - "d3-format": "^1.2.0", - "d3-hierarchy": "^1.1.5", - "d3-interpolate": "^1.1.5", - "d3-scale": "^1.0.6", - "d3-scale-chromatic": "^1.1.1", - "d3-shape": "^1.2.0", - "lodash": "^4.17.4", - "react-measure": "^2.0.2", - "react-motion": "^0.5.2", - "recompose": "^0.26.0" - } - }, - "@nivo/legends": { - "version": "0.42.0", - "resolved": "https://registry.npmjs.org/@nivo/legends/-/legends-0.42.0.tgz", - "integrity": "sha512-t82aKNaFtbY0mlE12caiSkXml73APMibH+gKsXECwhSutfGfgQzUbqBjPsNKJcMiWfG46noJ1MrFhDB3a6204g==", - "requires": { - "lodash": "^4.17.4", - "recompose": "^0.26.0" - } - }, - "@nivo/line": { - "version": "0.42.1", - "resolved": "https://registry.npmjs.org/@nivo/line/-/line-0.42.1.tgz", - "integrity": "sha512-X/nvNvwMqz10hACBL/owCONDeG78occ6Er0ay6/1n2h+Dm6zn2p6hiFyvu7QtsdwGeHOC5sePcz9O44bycbtoQ==", - "requires": { - "@nivo/core": "0.42.1", - "@nivo/legends": "0.42.0", - "d3-format": "^1.2.0", - "d3-scale": "^1.0.6", - "d3-shape": "^1.2.0", - "lodash": "^4.17.4", - "react-motion": "^0.5.2", - "recompose": "^0.26.0" - } - }, "abab": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/abab/-/abab-1.0.4.tgz", @@ -1827,11 +1785,6 @@ } } }, - "change-emitter": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/change-emitter/-/change-emitter-0.1.6.tgz", - "integrity": "sha1-6LL+PX8at9aaMhma/5HqaTFAlRU=" - }, "chardet": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", @@ -1948,6 +1901,11 @@ } } }, + "classnames": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.5.tgz", + "integrity": "sha1-+zgB1FNGdknvNgPH1hoCvRKb3m0=" + }, "clean-css": { "version": "4.1.11", "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.1.11.tgz", @@ -2590,11 +2548,6 @@ "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-1.3.0.tgz", "integrity": "sha512-ycfLEIzHVZC3rOvuBOKVyQXSiUyCDjeAPIj9n/wugrr+s5AcTQC2Bz6aKkubG7rQaQF0SGW/OV4UEJB9nfioFg==" }, - "d3-hierarchy": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-1.1.6.tgz", - "integrity": "sha512-nn4bhBnwWnMSoZgkBXD7vRyZ0xVUsNMQRKytWYHhP1I4qHw+qzApCTgSQTZqMdf4XXZbTMqA59hFusga+THA/g==" - }, "d3-interpolate": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-1.2.0.tgz", @@ -2609,9 +2562,9 @@ "integrity": "sha1-JB6xhJvZ6egCHA0KeZ+KDo5EF2Q=" }, "d3-scale": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-1.0.7.tgz", - "integrity": "sha512-KvU92czp2/qse5tUfGms6Kjig0AhHOwkzXG0+PqIJB3ke0WUv088AHMZI0OssO9NCkXt4RP8yju9rpH8aGB7Lw==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-1.0.6.tgz", + "integrity": "sha1-vOGdqA06DPQiyVQ64zIghiILNO0=", "requires": { "d3-array": "^1.2.0", "d3-collection": "1", @@ -2622,15 +2575,6 @@ "d3-time-format": "2" } }, - "d3-scale-chromatic": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-1.3.0.tgz", - "integrity": "sha512-YwMbiaW2bStWvQFByK8hA6hk7ToWflspIo2TRukCqERd8isiafEMBXmwfh8c7/0Z94mVvIzIveRLVC6RAjhgeA==", - "requires": { - "d3-color": "1", - "d3-interpolate": "1" - } - }, "d3-shape": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.2.0.tgz", @@ -2896,6 +2840,11 @@ } } }, + "dom-helpers": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.3.1.tgz", + "integrity": "sha512-2Sm+JaYn74OiTM2wHvxJOo3roiq/h25Yi69Fqk269cNUwIXsCvATB6CRSFC9Am/20G2b28hGv/+7NiWydIrPvg==" + }, "dom-serializer": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz", @@ -4567,11 +4516,6 @@ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==" }, - "get-node-dimensions": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/get-node-dimensions/-/get-node-dimensions-1.2.1.tgz", - "integrity": "sha512-2MSPMu7S1iOTL+BOa6K1S62hB2zUAYNF/lV0gSVlOaacd087lc6nR1H1r0e3B1CerTo+RceOmi1iJW+vp21xcQ==" - }, "get-stdin": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", @@ -4868,11 +4812,6 @@ "minimalistic-crypto-utils": "^1.0.1" } }, - "hoist-non-react-statics": { - "version": "2.5.5", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz", - "integrity": "sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw==" - }, "home-or-tmp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", @@ -6631,6 +6570,11 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==" }, + "lodash-es": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.10.tgz", + "integrity": "sha512-iesFYPmxYYGTcmQK0sL8bX3TGHyM6b2qREaB4kamHfQyfPJP0xgoGxp19nsH16nsfquLdiyKyX3mQkfiSGV8Rg==" + }, "lodash._reinterpolate": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", @@ -9022,32 +8966,10 @@ "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-4.0.0.tgz", "integrity": "sha512-FlsPxavEyMuR6TjVbSSywovXSEyOg6ZDj5+Z8nbsRl9EkOzAhEIcS+GLoQDC5fz/t9suhUXWmUrOBrgeUvrMxw==" }, - "react-measure": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/react-measure/-/react-measure-2.0.2.tgz", - "integrity": "sha1-ByqaX6/AHfutwfpfsJ/DUQN/Y2w=", - "requires": { - "get-node-dimensions": "^1.2.0", - "prop-types": "^15.5.10", - "resize-observer-polyfill": "^1.4.2" - } - }, - "react-motion": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/react-motion/-/react-motion-0.5.2.tgz", - "integrity": "sha512-9q3YAvHoUiWlP3cK0v+w1N5Z23HXMj4IF4YuvjvWegWqNPfLXsOBE/V7UvQGpXxHFKRQQcNcVQE31g9SB/6qgQ==", - "requires": { - "performance-now": "^0.2.0", - "prop-types": "^15.5.8", - "raf": "^3.1.0" - }, - "dependencies": { - "performance-now": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz", - "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=" - } - } + "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-placeholder": { "version": "3.0.1", @@ -9057,6 +8979,14 @@ "prop-types": "^15.6.0" } }, + "react-resize-detector": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/react-resize-detector/-/react-resize-detector-1.1.0.tgz", + "integrity": "sha512-68KVcQlhcWQGXMAie82YueCa4f4yqwEoiQbVyYlSgJEin1zMtNBLLeU/+6FLNf1TTgjwSfpbMTJTw/uU0HNgtQ==", + "requires": { + "prop-types": "^15.5.10" + } + }, "react-scripts": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-1.1.4.tgz", @@ -9118,6 +9048,28 @@ } } }, + "react-smooth": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-1.0.0.tgz", + "integrity": "sha1-sp2+vd3bBtIbWwiWIWf7nqwYl9g=", + "requires": { + "lodash": "~4.17.4", + "prop-types": "^15.6.0", + "raf": "^3.2.0", + "react-transition-group": "^2.2.1" + } + }, + "react-transition-group": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.4.0.tgz", + "integrity": "sha512-Xv5d55NkJUxUzLCImGSanK8Cl/30sgpOEMGc5m86t8+kZwrPxPCPcFqyx83kkr+5Lz5gs6djuvE5By+gce+VjA==", + "requires": { + "dom-helpers": "^3.3.1", + "loose-envify": "^1.3.1", + "prop-types": "^15.6.2", + "react-lifecycles-compat": "^3.0.4" + } + }, "read-pkg": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", @@ -9181,17 +9133,37 @@ "set-immediate-shim": "^1.0.1" } }, - "recompose": { - "version": "0.26.0", - "resolved": "https://registry.npmjs.org/recompose/-/recompose-0.26.0.tgz", - "integrity": "sha512-KwOu6ztO0mN5vy3+zDcc45lgnaUoaQse/a5yLVqtzTK13czSWnFGmXbQVmnoMgDkI5POd1EwIKSbjU1V7xdZog==", + "recharts": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/recharts/-/recharts-1.0.1.tgz", + "integrity": "sha512-FYKL6eGAxSDm6t32MlgxKHRz/yTPzbxOS9vg/EFwANA2kVbPTabMBNPL7OTJl0NZHKMUr1/L/1Dh6d8HWpOpPQ==", "requires": { - "change-emitter": "^0.1.2", - "fbjs": "^0.8.1", - "hoist-non-react-statics": "^2.3.1", - "symbol-observable": "^1.0.4" + "classnames": "2.2.5", + "core-js": "2.5.1", + "d3-interpolate": "^1.1.5", + "d3-scale": "1.0.6", + "d3-shape": "1.2.0", + "lodash": "~4.17.4", + "lodash-es": "~4.17.4", + "prop-types": "^15.6.0", + "react-resize-detector": "1.1.0", + "react-smooth": "1.0.0", + "recharts-scale": "0.3.2", + "reduce-css-calc": "1.3.0" + }, + "dependencies": { + "core-js": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.1.tgz", + "integrity": "sha1-rmh03GaTd4m4B1T/VCjfZoGcpQs=" + } } }, + "recharts-scale": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/recharts-scale/-/recharts-scale-0.3.2.tgz", + "integrity": "sha1-2sdiFxSkdl0VLLKtvDDHO4MSCMk=" + }, "recursive-readdir": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.1.tgz", @@ -9453,11 +9425,6 @@ "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" }, - "resize-observer-polyfill": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.0.tgz", - "integrity": "sha512-M2AelyJDVR/oLnToJLtuDJRBBWUGUvvGigj1411hXhAdyFWqMaqHp7TixW3FpiLuVaikIcR1QL+zqoJoZlOgpg==" - }, "resolve": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.6.0.tgz", @@ -10277,11 +10244,6 @@ "serviceworker-cache-polyfill": "^4.0.0" } }, - "symbol-observable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", - "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==" - }, "symbol-tree": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.2.tgz", diff --git a/priv/frontend/package.json b/priv/frontend/package.json index 45a1a3a..dc6005f 100644 --- a/priv/frontend/package.json +++ b/priv/frontend/package.json @@ -7,13 +7,13 @@ "@fortawesome/fontawesome-svg-core": "^1.2.0-14", "@fortawesome/free-solid-svg-icons": "^5.1.0-11", "@fortawesome/react-fontawesome": "0.1.0-11", - "@nivo/line": "^0.42.1", "ms": "^2.1.1", "prop-types": "^15.6.2", "react": "^16.4.0", "react-dom": "^16.4.0", "react-placeholder": "^3.0.1", - "react-scripts": "1.1.4" + "react-scripts": "1.1.4", + "recharts": "^1.0.1" }, "scripts": { "start": "react-scripts start", diff --git a/priv/frontend/src/components/Graph.css b/priv/frontend/src/components/Graph.css index 74d216d..914de07 100644 --- a/priv/frontend/src/components/Graph.css +++ b/priv/frontend/src/components/Graph.css @@ -1,4 +1,14 @@ .graph-container { width: 100%; - height: 10rem; +} + +.recharts-tooltip-wrapper .recharts-default-tooltip { + padding: 0 0.5rem !important; + border-radius: 0.2rem; + font-size: 0.85rem; + opacity: 0.85; +} + +.recharts-tooltip-item-value { + font-family: PragmataPro, Menlo, "DejaVu Sans Mono", monospace; } diff --git a/priv/frontend/src/components/Graph.js b/priv/frontend/src/components/Graph.js index c8a1c5e..7a4eb43 100644 --- a/priv/frontend/src/components/Graph.js +++ b/priv/frontend/src/components/Graph.js @@ -2,7 +2,16 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import ms from 'ms'; -import { ResponsiveLine } from '@nivo/line'; +import { + ResponsiveContainer, + AreaChart, + XAxis, + YAxis, + CartesianGrid, + Tooltip, + Area, + ReferenceLine, +} from 'recharts'; import './Graph.css'; @@ -30,20 +39,12 @@ export default class Graph extends Component { } processData() { - const { data: unprocessedData } = this.props; + const { data } = this.props; - const data = unprocessedData.map(([timestamp, latency]) => ({ - x: timestamp, - y: latency, - })).sort(({ x: a }, { x: b }) => a - b); - - return [ - { - id: 'latency', - color: 'hsl(220, 100%, 75%)', - data, - }, - ]; + return data.map(([timestamp, latency]) => ({ + timestamp, + latency, + })).sort(({ timestamp: a }, { timestamp: b }) => a - b); } isSmallScreen() { @@ -51,51 +52,43 @@ export default class Graph extends Component { } render() { - const leftAxis = { - format: (d) => `${d}ms`, - tickCount: 3, - legend: 'latency', - legendPosition: 'center', - legendOffset: -55, - tickSize: 0, - }; - - const minutesAllocated = []; - return (
- `${d}ms`} - - axisLeft={this.isSmallScreen() ? null : leftAxis} - - axisBottom={{ - format: (epoch) => { - const interval = this.isSmallScreen() ? 7 : 5; - const minutesAgo = Math.floor((Date.now() - epoch) / (1000 * 60)); - - if (minutesAgo % interval !== 0 || minutesAgo === 0 - || minutesAllocated.includes(minutesAgo)) { - return ''; - } - - minutesAllocated.push(minutesAgo); - return ms(Date.now() - epoch); - }, - tickSize: 0, - legend: 'time ago', - legendPosition: 'center', - legendOffset: 40, - }} - - enableDots={false} - enableArea - /> + + + ms(Date.now() - tick)} + tickLine={false} + /> + + + `${value}ms`} + label="DAB" + separator=": " + labelFormatter={() => null} + /> + + + +
); } diff --git a/priv/frontend/src/components/ServicePlaceholder.js b/priv/frontend/src/components/ServicePlaceholder.js index 2da6347..4b97545 100644 --- a/priv/frontend/src/components/ServicePlaceholder.js +++ b/priv/frontend/src/components/ServicePlaceholder.js @@ -38,7 +38,7 @@ const ServicePlaceholder = () => ( {' '}