@netdata/charts
Version:
Netdata frontend SDK and chart utilities
170 lines (169 loc) • 9.23 kB
JavaScript
;
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);