UNPKG

@netdata/charts

Version:

Netdata frontend SDK and chart utilities

170 lines (169 loc) 9.23 kB
"use strict"; function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _react = _interopRequireWildcard(require("react")); var _styledComponents = _interopRequireWildcard(require("styled-components")); var _netdataUi = require("@netdata/netdata-ui"); var _headlessChart = require("../headlessChart"); var _provider = require("../provider"); var _jsxRuntime = require("react/jsx-runtime"); function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, "default": e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); } function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); } function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } } function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); } function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); } function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; } var colorMap = { WARNING: "#FFC300", CRITICAL: "#FF4136", CLEAR: "#00AB44" }; var DEFAULT_HOVER_COLOR = "#808080"; var Container = (0, _styledComponents["default"])(_netdataUi.Flex).withConfig({ displayName: "alertTimeline__Container", componentId: "sc-1bv52bo-0" })(["position:relative;height:16px;cursor:crosshair;"]); var Segment = _styledComponents["default"].div.withConfig({ displayName: "alertTimeline__Segment", componentId: "sc-1bv52bo-1" })(["position:absolute;height:4px;top:50%;transform:translateY(-50%);"]); var Dot = _styledComponents["default"].div.withConfig({ displayName: "alertTimeline__Dot", componentId: "sc-1bv52bo-2" })(["position:absolute;width:10px;height:10px;border-radius:50%;top:50%;transform:translate(-50%,-50%);border:2px solid ", ";box-sizing:border-box;z-index:1;"], function (_ref) { var theme = _ref.theme; return theme.colors.mainBackground; }); var pulse = (0, _styledComponents.keyframes)(["0%{opacity:1;box-shadow:0 0 4px 1px var(--pulse-color);}50%{opacity:0.7;box-shadow:0 0 8px 3px var(--pulse-color);}100%{opacity:1;box-shadow:0 0 4px 1px var(--pulse-color);}"]); var HoverIndicator = _styledComponents["default"].div.withConfig({ displayName: "alertTimeline__HoverIndicator", componentId: "sc-1bv52bo-3" })(["position:absolute;width:2px;height:100%;background:var(--pulse-color);top:0;transform:translateX(-50%);pointer-events:none;z-index:2;border-radius:1px;animation:", " 1.2s ease-in-out infinite;"], pulse); var parseTimestamp = function parseTimestamp(timestamp) { if (typeof timestamp === "number") return timestamp * 1000; return new Date(timestamp).getTime(); }; var AlertTimeline = function AlertTimeline() { var _chart$getAttribute, _hover$; var containerRef = (0, _react.useRef)(null); var _useHeadlessChart = (0, _headlessChart.useHeadlessChart)(), chart = _useHeadlessChart.chart, hover = _useHeadlessChart.hover, helpers = _useHeadlessChart.helpers, attributes = _useHeadlessChart.attributes; var _usePlotArea = (0, _provider.usePlotArea)(), plotLeft = _usePlotArea.left, plotWidth = _usePlotArea.width; var _ref2 = ((_chart$getAttribute = chart.getAttribute("overlays")) === null || _chart$getAttribute === void 0 ? void 0 : _chart$getAttribute.alertTransitions) || {}, _ref2$transitions = _ref2.transitions, transitions = _ref2$transitions === void 0 ? [] : _ref2$transitions, _ref2$showCleared = _ref2.showCleared, showCleared = _ref2$showCleared === void 0 ? true : _ref2$showCleared; var after = attributes.after; var before = attributes.before; var now = Date.now(); var viewStart = after < 0 ? now + after * 1000 : after * 1000; var viewEnd = before <= 0 ? now : before * 1000; var viewDuration = viewEnd - viewStart; var getPositionPercent = (0, _react.useCallback)(function (timestampMs) { if (viewDuration <= 0) return 0; return (timestampMs - viewStart) / viewDuration * 100; }, [viewStart, viewDuration]); var sortedTransitions = _toConsumableArray(transitions).sort(function (a, b) { return parseTimestamp(a.timestamp) - parseTimestamp(b.timestamp); }); var segments = []; var dots = []; sortedTransitions.forEach(function (transition, index) { var startMs = parseTimestamp(transition.timestamp); var nextTransition = sortedTransitions[index + 1]; var endMs = nextTransition ? parseTimestamp(nextTransition.timestamp) : viewEnd; if (endMs < viewStart || startMs > viewEnd) return; var state = transition.to.toUpperCase(); var color = colorMap[state]; if (!color) return; if (!showCleared && state === "CLEAR") return; var clampedStart = Math.max(viewStart, startMs); var clampedEnd = Math.min(viewEnd, endMs); var leftPercent = getPositionPercent(clampedStart); var rightPercent = getPositionPercent(clampedEnd); var widthPercent = rightPercent - leftPercent; segments.push({ key: "segment-".concat(index), left: "".concat(leftPercent, "%"), width: "".concat(widthPercent, "%"), color: color }); if (startMs >= viewStart && startMs <= viewEnd) { dots.push({ key: "dot-".concat(index), left: "".concat(getPositionPercent(startMs), "%"), color: color }); } }); var hoverTimestamp = (_hover$ = hover === null || hover === void 0 ? void 0 : hover[0]) !== null && _hover$ !== void 0 ? _hover$ : null; var hoverPercent = hoverTimestamp ? getPositionPercent(hoverTimestamp) : null; var getColorAtTimestamp = function getColorAtTimestamp(timestamp) { if (!timestamp) return DEFAULT_HOVER_COLOR; for (var i = sortedTransitions.length - 1; i >= 0; i--) { var transition = sortedTransitions[i]; var transitionMs = parseTimestamp(transition.timestamp); if (timestamp >= transitionMs) { var state = transition.to.toUpperCase(); if (!showCleared && state === "CLEAR") return DEFAULT_HOVER_COLOR; return colorMap[state] || DEFAULT_HOVER_COLOR; } } return DEFAULT_HOVER_COLOR; }; var hoverColor = getColorAtTimestamp(hoverTimestamp); var handleMouseMove = (0, _react.useCallback)(function (event) { if (!containerRef.current) return; var rect = containerRef.current.getBoundingClientRect(); var x = event.clientX - rect.left; var percent = x / rect.width; var timestamp = viewStart + percent * viewDuration; chart.sdk.trigger("highlightHover", chart, timestamp, null); chart.trigger("highlightHover", timestamp, null); }, [chart, viewStart, viewDuration]); var handleMouseLeave = (0, _react.useCallback)(function () { chart.sdk.trigger("highlightBlur", chart); chart.trigger("highlightBlur"); }, [chart]); return /*#__PURE__*/(0, _jsxRuntime.jsxs)(Container, { ref: containerRef, onMouseMove: handleMouseMove, onMouseLeave: handleMouseLeave, style: { marginLeft: plotLeft, width: plotWidth }, children: [segments.map(function (segment) { return /*#__PURE__*/(0, _jsxRuntime.jsx)(Segment, { style: { left: segment.left, width: segment.width, backgroundColor: segment.color } }, segment.key); }), dots.map(function (dot) { return /*#__PURE__*/(0, _jsxRuntime.jsx)(Dot, { style: { left: dot.left, backgroundColor: dot.color } }, dot.key); }), hoverPercent !== null && hoverPercent >= 0 && hoverPercent <= 100 && /*#__PURE__*/(0, _jsxRuntime.jsx)(HoverIndicator, { style: { left: "".concat(hoverPercent, "%"), "--pulse-color": hoverColor } })] }); }; var _default = exports["default"] = /*#__PURE__*/(0, _react.memo)(AlertTimeline);