@netdata/charts
Version:
Netdata frontend SDK and chart utilities
310 lines (309 loc) • 16.7 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 _netdataUi = require("@netdata/netdata-ui");
var _provider = require("../provider");
var _dropdownSingleSelect = _interopRequireDefault(require("./dropdownSingleSelect"));
var _jsxRuntime = require("react/jsx-runtime");
var _excluded = ["labelProps"];
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
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 ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
function _toArray(r) { return _arrayWithHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure 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 _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; }
function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
var useMenuItems = function useMenuItems(chart) {
var perTier = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
var _perTier = _toArray(perTier),
firstTier = _perTier[0],
restTiers = _arrayLikeToArray(_perTier).slice(1);
return (0, _react.useMemo)(function () {
return [{
value: "min",
label: "Minimum",
description: "Reveal short dives that would otherwise be smoothed out.",
"short": "MIN()",
"data-track": chart.track("time-aggregation-min")
}, {
value: "max",
label: "Maximum",
description: "Reveal short spikes that would otherwise be smoothed out.",
"short": "MAX()",
"data-track": chart.track("time-aggregation-max")
}, {
value: "average",
label: "Mean or Average",
description: "Calculate the longer term average, as if data were collected at screen resolution.",
"short": "AVG()",
"data-track": chart.track("time-aggregation-average")
}, {
value: "sum",
label: "Sum",
description: "Provide the sum of the points that are aggregated over time. Use it when a sense of volume is needed over the aggregation period. It may not be sensible to use this function on all data types.",
"short": "SUM()",
"data-track": chart.track("time-aggregation-sum")
}, Array.isArray(restTiers) && typeof (firstTier === null || firstTier === void 0 ? void 0 : firstTier.points) !== "undefined" && {
justDesc: true,
description: "The functions below lose accuracy when applied on tiered data, compared to high resolution data. Your current query is ".concat(firstTier.points * 100.0 / perTier.reduce(function (h, t) {
return h + t.points;
}, 0), "% high resolution and ").concat(restTiers.reduce(function (h, t) {
return h + t.points;
}, 0) * 100.0 / perTier.reduce(function (h, t) {
return h + t.points;
}, 0).toFixed(2), "% tiered data of lower resolution.")
}, {
value: "percentile",
label: "Percentile",
description: "Provide the maximum value of a percentage of the aggregated points, having the smaller values. The default is p95, which provides the maximum value of the aggregated points after ignoring the top 5% of them.",
"short": "PERCENTILE()",
"data-track": chart.track("time-aggregation-percentile95")
}, {
value: "trimmed-mean",
label: "Trimmed Average or Trimmed Mean",
description: "Like average, but first remove a percentage of the extreme high and low values.",
"short": "TRIMMEAN()",
"data-track": chart.track("time-aggregation-trimmed-mean5")
}, {
value: "median",
label: "Median",
description: "The middle value of all points that would otherwise be smoothed out. This function works like average, but short extreme dives and spikes influence it significantly less than average.",
"short": "MEDIAN()",
"data-track": chart.track("time-aggregation-median")
}, {
value: "trimmed-median",
label: "Trimmed Median",
description: "Like median, but first remove a percentage of the extreme high and low values.",
"short": "TRIMMEDIAN()",
"data-track": chart.track("time-aggregation-trimmed-median5")
}, {
value: "stddev",
label: "Standard deviation",
description: "Reveal how far each point lies from the average. A high standard deviation means that values are generally far from the average, while a low standard deviation indicates that values are clustered close to the mean. The result is again in the original units of the data source metric.",
"short": "STDDEV()",
"data-track": chart.track("time-aggregation-stddev")
}, {
value: "cv",
label: "Coefficient of variation or Relative standard deviation",
description: "The ratio of the standard deviation to the average. Its use is the same as standard deviation, but expressed as a percentage related to the average. The units change to %.",
"short": "CV()",
"data-track": chart.track("time-aggregation-cv")
}, {
value: "incremental-sum",
label: "Incremental Sum or Delta",
description: "Provide the difference between the newest and the oldest values of the aggregated points. Each point will be positive if the trend grows and negative if the trend shrinks.",
"short": "DELTA()",
"data-track": chart.track("time-aggregation-incremental-sum")
}, {
value: "ses",
label: "Single exponential smoothing",
description: "Use the aggregated points to produce a forecast of the next value, and reveal the forecasted value. Use it when there are indications that the trend is more predictable using the more recent points than the older ones.",
"short": "SES()",
"data-track": chart.track("time-aggregation-ses")
}, {
value: "des",
label: "Double exponential smoothing",
description: "Like single exponential smoothing, but better suited when the aggregated points may have a strong trend.",
"short": "DES()",
"data-track": chart.track("time-aggregation-des")
}].filter(Boolean);
}, [chart, firstTier === null || firstTier === void 0 ? void 0 : firstTier.points]);
};
var useMenuAliasItems = function useMenuAliasItems(_ref) {
var chart = _ref.chart,
method = _ref.method;
return (0, _react.useMemo)(function () {
if (method === "percentile") {
return [{
value: "25",
label: "25th",
"short": "25th",
"data-track": chart.track("time-aggregation-percentile25")
}, {
value: "50",
label: "50th",
"short": "50th",
"data-track": chart.track("time-aggregation-percentile50")
}, {
value: "75",
label: "75th",
"short": "75th",
"data-track": chart.track("time-aggregation-percentile75")
}, {
value: "80",
label: "80th",
"short": "80th",
"data-track": chart.track("time-aggregation-percentile80")
}, {
value: "90",
label: "90th",
"short": "90th",
"data-track": chart.track("time-aggregation-percentile90")
}, {
value: "95",
label: "95th",
"short": "95th",
"data-track": chart.track("time-aggregation-percentile95")
}, {
value: "97",
label: "97th",
"short": "97th",
"data-track": chart.track("time-aggregation-percentile97")
}, {
value: "98",
label: "98th",
"short": "98th",
"data-track": chart.track("time-aggregation-percentile98")
}, {
value: "99",
label: "99th",
"short": "99th",
"data-track": chart.track("time-aggregation-percentile99")
}];
}
if (method.includes("trimmed")) {
return [{
value: "1",
label: "1%",
"short": "1%",
"data-track": chart.track("time-aggregation-".concat(method, "1"))
}, {
value: "2",
label: "2%",
"short": "2%",
"data-track": chart.track("time-aggregation-".concat(method, "2"))
}, {
value: "3",
label: "3%",
"short": "3%",
"data-track": chart.track("time-aggregation-".concat(method, "3"))
}, {
value: "5",
label: "5%",
"short": "5%",
"data-track": chart.track("time-aggregation-".concat(method, "5"))
}, {
value: "10",
label: "10%",
"short": "10%",
"data-track": chart.track("time-aggregation-".concat(method, "10"))
}, {
value: "15",
label: "15%",
"short": "15%",
"data-track": chart.track("time-aggregation-".concat(method, "15"))
}, {
value: "20",
label: "20%",
"short": "20%",
"data-track": chart.track("time-aggregation-".concat(method, "20"))
}, {
value: "25",
label: "25%",
"short": "25%",
"data-track": chart.track("time-aggregation-".concat(method, "25"))
}];
}
return [];
}, [chart, method]);
};
var defaultAliases = {
percentile: "95",
"trimmed-mean": "5",
"trimmed-median": "5"
};
var aliasTooltipProps = {
heading: "Aliases aggregation over time",
body: "The percentile or percentage of the data you want to focus for the percentile or trimmed functions selected."
};
var methodTooltipProps = {
heading: "Time aggregation",
body: "View or select the aggregation function applied on each time-series metric when the number of points in the database are more than the points your screen resolution provides to present this chart. This function is helpful when viewing long time-frames, like days, weeks or months, to quickly spot anomalies, spikes or dives."
};
var dropTitle = /*#__PURE__*/(0, _jsxRuntime.jsx)(_netdataUi.TextMicro, {
padding: [0, 0, 2],
color: "textLite",
children: "When the screen resolution provides less points than the points available of the source time-series metrics, use the following aggregation function over time on each metric to reduce the number of points"
});
var TimeAggregation = function TimeAggregation(_ref2) {
var labelProps = _ref2.labelProps,
rest = _objectWithoutProperties(_ref2, _excluded);
var chart = (0, _provider.useChart)();
var groupingMethod = (0, _provider.useAttributeValue)("groupingMethod");
var _ref3 = groupingMethod.match(/[\d.]+|\D+/g) || [],
_ref4 = _slicedToArray(_ref3, 2),
_ref4$ = _ref4[0],
method = _ref4$ === void 0 ? "" : _ref4$,
_ref4$2 = _ref4[1],
alias = _ref4$2 === void 0 ? "" : _ref4$2;
var viewUpdateEvery = (0, _provider.useAttributeValue)("viewUpdateEvery");
var perTier = (0, _provider.useAttributeValue)("perTier");
var items = useMenuItems(chart, perTier);
var aliasItems = useMenuAliasItems({
chart: chart,
method: method
});
var _ref5 = items.find(function (item) {
return item.value === method;
}) || items[0],
_short = _ref5["short"];
var aliasItem = aliasItems.find(function (item) {
return item.value === alias;
}) || aliasItems[0];
var handleAliasChange = function handleAliasChange(value) {
return chart.updateTimeAggregationMethodAttribute({
alias: value,
method: method
});
};
var handleMethodChange = function handleMethodChange(value) {
return chart.updateTimeAggregationMethodAttribute({
alias: defaultAliases[value],
method: value
});
};
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_netdataUi.Flex, {
children: [alias && /*#__PURE__*/(0, _jsxRuntime.jsx)(_dropdownSingleSelect["default"], _objectSpread(_objectSpread({
value: alias,
onChange: handleAliasChange,
items: aliasItems,
"data-track": chart.track("groupingMethodAlias")
}, rest), {}, {
labelProps: _objectSpread({
secondaryLabel: "each as",
label: aliasItem["short"],
title: aliasTooltipProps.heading,
tooltipProps: aliasTooltipProps
}, labelProps)
})), /*#__PURE__*/(0, _jsxRuntime.jsx)(_dropdownSingleSelect["default"], _objectSpread(_objectSpread({
value: method,
onChange: handleMethodChange,
items: items,
"data-track": chart.track("groupingMethod"),
dropTitle: dropTitle
}, rest), {}, {
labelProps: _objectSpread({
secondaryLabel: !alias && "each as",
tertiaryLabel: "every ".concat(viewUpdateEvery, "s"),
label: _short,
title: methodTooltipProps.heading,
tooltipProps: methodTooltipProps
}, labelProps)
}))]
});
};
var _default = exports["default"] = /*#__PURE__*/(0, _react.memo)(TimeAggregation);