@netdata/charts
Version:
Netdata frontend SDK and chart utilities
341 lines • 16.9 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); }
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 _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 _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 _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _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 _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 _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
import makeKeyboardListener from "../../helpers/makeKeyboardListener";
import makeExecuteLatest from "../../helpers/makeExecuteLatest";
import convert from "../../helpers/units";
import unitConversion from "../../helpers/unitConversion";
import makeNode from "../makeNode";
import { fetchChartData } from "./api";
import makeDimensions from "./makeDimensions";
import makeFilterControllers from "./filters/makeControllers";
import makeDataFetch from "./makeDataFetch";
import makeGetUnitSign from "./makeGetUnitSign";
import makeWeights from "./makeWeights";
var themeIndex = {
"default": 0,
dark: 1
};
var maxBackoffMs = 30 * 1000;
var defaultMakeTrack = function defaultMakeTrack() {
return function (value) {
return value;
};
};
export default (function () {
var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
sdk = _ref.sdk,
parent = _ref.parent,
_ref$getChart = _ref.getChart,
getChart = _ref$getChart === void 0 ? fetchChartData : _ref$getChart,
attributes = _ref.attributes,
_ref$makeTrack = _ref.makeTrack,
makeTrack = _ref$makeTrack === void 0 ? defaultMakeTrack : _ref$makeTrack;
var executeLatest = makeExecuteLatest();
var node = makeNode({
sdk: sdk,
parent: parent,
attributes: attributes
});
node.getChart = getChart;
var fetchTimeoutId = null;
node.getRoot = function () {
return sdk.getRoot();
};
node.backoffMs = null;
node.backoff = function (ms) {
if (!node) return;
if (ms) {
node.backoffMs = ms;
return;
}
var tmpBackoffMs = node.backoffMs ? node.backoffMs * 2 : node.getUpdateEvery();
node.backoffMs = tmpBackoffMs > maxBackoffMs ? maxBackoffMs : tmpBackoffMs;
};
var uiInstances = {};
node.getUpdateEvery = function () {
if (!node) return;
var _node$getAttributes = node.getAttributes(),
loaded = _node$getAttributes.loaded,
viewUpdateEvery = _node$getAttributes.viewUpdateEvery,
updateEvery = _node$getAttributes.updateEvery;
if (viewUpdateEvery) return viewUpdateEvery * 1000;
return loaded ? updateEvery * 1000 || 1000 : 0;
};
var cachedDateWindow = null;
var prevAfter = null;
var prevRenderedAt = null;
var prevNow = null;
node.getDateWindow = function () {
var _node$getAttributes2 = node.getAttributes(),
after = _node$getAttributes2.after,
before = _node$getAttributes2.before,
renderedAt = _node$getAttributes2.renderedAt;
var now = sdk.getRoot().getAttribute("fetchAt", Date.now());
if (prevAfter === after && prevRenderedAt === renderedAt && prevNow === now) return cachedDateWindow;
prevAfter = after;
prevRenderedAt = renderedAt;
prevNow = now;
cachedDateWindow = after > 0 ? [after * 1000, before * 1000] : renderedAt ? [renderedAt + after * 1000, renderedAt] : [now + after * 1000, now];
return cachedDateWindow;
};
node.startAutofetch = function () {
if (!node) return;
var _node$getAttributes3 = node.getAttributes(),
fetchStartedAt = _node$getAttributes3.fetchStartedAt,
loading = _node$getAttributes3.loading,
autofetch = _node$getAttributes3.autofetch,
active = _node$getAttributes3.active;
if (!autofetch || loading || !active) return;
if (node.getRoot().getAttribute("paused")) return;
if (fetchStartedAt === 0) {
node.trigger("fetch");
return;
}
var fetchingPeriod = Date.now() - fetchStartedAt;
var updateEveryMs = node.getUpdateEvery();
var div = fetchingPeriod / updateEveryMs;
var updateEveryMultiples = Math.floor(div);
if (updateEveryMultiples >= 1) {
node.lastFetch = node.getDateWindow();
node.trigger("fetch");
return;
}
var remaining = node.backoffMs || updateEveryMs - Math.round((div - Math.floor(div)) * updateEveryMs);
clearTimeout(fetchTimeoutId);
fetchTimeoutId = setTimeout(function () {
node.startAutofetch();
}, remaining);
};
node.getUI = function () {
var uiName = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "default";
return uiInstances[uiName];
};
node.setUI = function (newUi) {
var uiName = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "default";
uiInstances[uiName] = newUi;
};
var render = executeLatest.add(function () {
return Object.keys(uiInstances).forEach(function (uiName) {
return uiInstances[uiName].render();
});
});
node.on("render", render);
unitConversion(node);
node.getConvertedValue = function (value) {
var _ref2 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
fractionDigits = _ref2.fractionDigits,
_ref2$key = _ref2.key,
key = _ref2$key === void 0 ? "units" : _ref2$key,
dimensionId = _ref2.dimensionId;
if (!node) return;
if (value === null) return "-";
var _node$getUnitAttribut = node.getUnitAttributes(dimensionId, key),
method = _node$getUnitAttribut.method,
unitsConversionFractionDigits = _node$getUnitAttribut.fractionDigits,
divider = _node$getUnitAttribut.divider;
var converted = convert(node, method, value, divider);
if (isNaN(converted)) return converted;
return Intl.NumberFormat(undefined, {
useGrouping: true,
minimumFractionDigits: isNaN(fractionDigits) || fractionDigits < 0 ? 0 : fractionDigits,
maximumFractionDigits: isNaN(fractionDigits) || fractionDigits < 0 ? unitsConversionFractionDigits === -1 ? 4 : unitsConversionFractionDigits : fractionDigits
}).format(converted);
};
node.focus = function (event) {
if (!node) return;
if (node.getAttribute("focused") && node.getAttribute("hovering")) return;
node.updateAttributes({
focused: true
});
sdk.trigger("hoverChart", node, event);
node.trigger("hoverChart", event);
};
node.blur = function (event) {
if (!node) return;
if (!node.getAttribute("focused") && !node.getAttribute("hovering")) return;
node.updateAttributes({
focused: false
});
sdk.trigger("blurChart", node, event);
node.trigger("blurChart", event);
};
node.activate = function () {
if (!node) return;
node.updateAttribute("active", true);
sdk.trigger("active", node, true);
};
node.deactivate = function () {
if (!node) return;
node.updateAttribute("active", false);
sdk.trigger("active", node, false);
};
node.getFirstEntry = function () {
return node.getAttribute("firstEntry");
};
node.getUnits = function () {
if (!node) return;
var _node$getAttributes4 = node.getAttributes(),
units = _node$getAttributes4.units;
return units;
};
node.getApplicableNodes = function (attributes, options) {
if (!node) return [];
if (!node.match(attributes)) return [node];
var ancestor = node.getAncestor(attributes);
if (!ancestor) return [node];
return ancestor.getNodes(attributes, options);
};
node.stopAutofetch = function () {
var force = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
clearTimeout(fetchTimeoutId);
if (!node || !force) return;
if (!node.getAttribute("active") && node.getAttribute("loaded") && node.getAttribute("loading")) {
node.cancelFetch();
}
};
makeDimensions(node, sdk);
makeDataFetch(node, sdk);
makeWeights(node, sdk);
node.type = "chart";
makeGetUnitSign(node);
node.track = makeTrack(node);
var _makeKeyboardListener = makeKeyboardListener(),
onKeyChange = _makeKeyboardListener.onKeyChange,
initKeyboardListener = _makeKeyboardListener.initKeyboardListener,
clearKeyboardListener = _makeKeyboardListener.clearKeyboardListener;
onKeyChange(["Alt", "Shift", "KeyF"], function () {
if (!node) return;
node.updateAttribute("fullscreen", !node.getAttribute("fullscreen"));
});
onKeyChange(["Alt", "Shift", "KeyR"], function () {
if (!node) return;
node.resetNavigation();
});
node.onAttributeChange("autofetch", function (autofetch) {
if (!node) return;
if (autofetch) {
node.startAutofetch();
} else {
node.stopAutofetch(false);
}
});
node.onAttributeChange("active", function (active) {
if (!node) return;
if (!active) return node.stopAutofetch();
if (node.getAttribute("autofetch")) return node.startAutofetch();
});
node.onAttributeChange("focused", function (focused) {
if (!node) return;
focused ? initKeyboardListener() : clearKeyboardListener();
node.invalidateClosestRowCache();
});
node.makeChartUI = function (uiName) {
var chartLibrary = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : node.getAttribute("chartLibrary");
var force = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
if (!(chartLibrary in sdk.ui)) console.error("Chart library \"".concat(chartLibrary, "\" does not exist in ").concat(Object.keys(sdk.ui).join(", ")));
if (node.getUI(uiName) && !force) return;
var makeChartLibrary = sdk.ui[chartLibrary];
var chartUi = makeChartLibrary(sdk, node);
node.setUI(chartUi, uiName);
};
node.makeSubChart = function () {
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var subChart = sdk.makeChartCore(options);
var chartUi = sdk.makeChartUI(subChart);
subChart.setUI(chartUi, "default");
return subChart;
};
node.getThemeIndex = function () {
if (!node) return;
return themeIndex[node.getAttribute("theme")] || themeIndex["default"];
};
node.getThemeAttribute = function (name) {
var _attributes$name;
if (!node) return;
var attributes = node.getAttributes();
var index = node.getThemeIndex();
return ((_attributes$name = attributes[name]) === null || _attributes$name === void 0 ? void 0 : _attributes$name[index]) || name;
};
node.getNodeIdsForHostLabels = function (fallback) {
var _node$getAttributes5 = node.getAttributes(),
selectedNodeLabelsFilter = _node$getAttributes5.selectedNodeLabelsFilter,
nodesScope = _node$getAttributes5.nodesScope,
nodes = _node$getAttributes5.nodes,
nodesById = _node$getAttributes5.nodesById;
var byLabel = (selectedNodeLabelsFilter || []).reduce(function (h, label) {
var _label$split = label.split("|"),
_label$split2 = _slicedToArray(_label$split, 2),
key = _label$split2[0],
value = _label$split2[1];
if (!h[key]) h[key] = [];
h[key].push(value);
return h;
}, {});
var dbNodeIds = Object.keys(nodes);
var nodeIds = dbNodeIds.length ? dbNodeIds : nodesScope.length ? nodesScope : nodesById ? Object.keys(nodesById) : [];
if (!nodesById) return fallback !== null && fallback !== void 0 ? fallback : nodeIds;
return nodeIds.filter(function (id) {
return !!nodesById[id] && Object.keys(byLabel).every(function (label) {
return byLabel[label].length ? "".concat(byLabel[label]).includes(nodesById[id].labels[label]) : false;
});
});
};
node.getFilteredNodeIds = function () {
var _node$getAttributes6 = node.getAttributes(),
selectedNodeLabelsFilter = _node$getAttributes6.selectedNodeLabelsFilter,
nodesById = _node$getAttributes6.nodesById,
selectedNodes = _node$getAttributes6.selectedNodes;
if (!(selectedNodeLabelsFilter !== null && selectedNodeLabelsFilter !== void 0 && selectedNodeLabelsFilter.length) || !nodesById) return selectedNodes;
var nodeIdsForHostLabels = node.getNodeIdsForHostLabels();
return _toConsumableArray(new Set([].concat(_toConsumableArray(selectedNodes), _toConsumableArray(nodeIdsForHostLabels))));
};
var destroy = function destroy() {
if (!node) return;
if (executeLatest) executeLatest.clear();
node.destroy();
node.stopAutofetch();
clearKeyboardListener();
Object.keys(uiInstances).forEach(function (uiName) {
return uiInstances[uiName].unmount();
});
setTimeout(function () {
uiInstances = null;
node = null;
}, 2000);
node.destroy();
};
node.intl = function (key) {
var _en$key, _en$key2;
var _ref3 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
_ref3$count = _ref3.count,
count = _ref3$count === void 0 ? 1 : _ref3$count,
_ref3$pluralize = _ref3.pluralize,
pluralize = _ref3$pluralize === void 0 ? true : _ref3$pluralize,
_ref3$fallback = _ref3.fallback,
fallback = _ref3$fallback === void 0 ? "" : _ref3$fallback;
if (!node) return key;
var en = node.getAttribute("en");
if (!(en !== null && en !== void 0 && en[key])) return count === 1 ? fallback || key : pluralize ? "".concat(fallback || key, "s") : fallback || key;
if (typeof en[key] === "string") return en[key];
return count === 1 ? ((_en$key = en[key]) === null || _en$key === void 0 ? void 0 : _en$key.one) || key : ((_en$key2 = en[key]) === null || _en$key2 === void 0 ? void 0 : _en$key2.other) || (pluralize ? "".concat(key, "s") : key);
};
return _objectSpread(_objectSpread(_objectSpread({}, node), makeFilterControllers(node)), {}, {
destroy: destroy,
onKeyChange: onKeyChange,
sdk: sdk
});
});