@netdata/charts
Version:
Netdata frontend SDK and chart utilities
176 lines • 7.24 kB
JavaScript
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 { groupByContext, transformCorrelationData } from "./dataTransformer";
var schema = {
type: "array",
items: [{
name: "weight"
}, {
name: "timeframe"
}, {
name: "baseline timeframe"
}]
};
var makeItem = function makeItem() {
var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
_ref$dimension = _ref.dimension,
dimension = _ref$dimension === void 0 ? "dimension-id" : _ref$dimension,
_ref$dimensionName = _ref.dimensionName,
dimensionName = _ref$dimensionName === void 0 ? "Dimension name" : _ref$dimensionName,
_ref$context = _ref.context,
context = _ref$context === void 0 ? "context-id" : _ref$context,
_ref$contextName = _ref.contextName,
contextName = _ref$contextName === void 0 ? "Context name" : _ref$contextName,
_ref$node = _ref.node,
node = _ref$node === void 0 ? "node-id" : _ref$node,
_ref$nodeName = _ref.nodeName,
nodeName = _ref$nodeName === void 0 ? "Node name" : _ref$nodeName,
_ref$weight = _ref.weight,
weight = _ref$weight === void 0 ? 0.005 : _ref$weight,
_ref$timeframeAvg = _ref.timeframeAvg,
timeframeAvg = _ref$timeframeAvg === void 0 ? 15 : _ref$timeframeAvg,
_ref$baselineAvg = _ref.baselineAvg,
baselineAvg = _ref$baselineAvg === void 0 ? 10 : _ref$baselineAvg;
return {
values: {
dimension: dimension,
context: context,
node: node
},
names: {
dimension: dimensionName,
context: contextName,
node: nodeName
},
v: [[weight, weight, weight, weight, 1], [0, timeframeAvg, 0, 0, 10, 0], [0, baselineAvg, 0, 0, 8, 0]]
};
};
var makeResponse = function makeResponse(items) {
var groupBy = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ["dimension", "node", "context"];
return {
request: {
aggregations: {
metrics: [{
group_by: groupBy
}]
}
},
v_schema: schema,
result: items.map(function (item) {
return {
id: groupBy.map(function (field) {
return item.values[field];
}).join(","),
nm: groupBy.map(function (field) {
return item.names[field];
}).join(","),
v: item.v
};
})
};
};
describe("transformCorrelationData", function () {
it.each([["dimension", "node", "context"], ["node", "context", "dimension"], ["context", "dimension", "node"]])("uses the response group order: %s, %s, %s", function () {
for (var _len = arguments.length, groupBy = new Array(_len), _key = 0; _key < _len; _key++) {
groupBy[_key] = arguments[_key];
}
var _transformCorrelation = transformCorrelationData(makeResponse([makeItem()], groupBy), 0.01),
_transformCorrelation2 = _slicedToArray(_transformCorrelation, 1),
result = _transformCorrelation2[0];
expect(result).toMatchObject({
dimension: "dimension-id",
dimensionName: "Dimension name",
context: "context-id",
contextName: "Context name",
nodeId: "node-id",
nodeName: "Node name",
correlationWeight: 0.005,
percentChange: 50
});
});
it("rejects responses that cannot identify every required group", function () {
var response = makeResponse([makeItem()], ["node", "dimension"]);
expect(transformCorrelationData(response)).toEqual([]);
expect(transformCorrelationData({
result: [],
v_schema: schema
})).toEqual([]);
});
it("filters by threshold and excludes the chart's own contexts", function () {
var response = makeResponse([makeItem({
context: "current",
weight: 0.001
}), makeItem({
context: "included",
weight: -0.009
}), makeItem({
context: "too-weak",
weight: 0.01
})]);
var result = transformCorrelationData(response, 0.01, ["current"]);
expect(result.map(function (item) {
return item.context;
})).toEqual(["included"]);
});
it("ignores malformed result rows", function () {
var response = makeResponse([makeItem()]);
response.result.push({
id: "invalid",
nm: "invalid",
v: []
});
expect(transformCorrelationData(response, 0.01)).toHaveLength(1);
});
});
describe("groupByContext", function () {
it("builds stable hierarchical rows ordered by strongest correlation", function () {
var response = makeResponse([makeItem({
dimension: "a",
context: "context-a",
weight: 0.008
}), makeItem({
dimension: "b",
context: "context-b",
weight: 0.002
}), makeItem({
dimension: "c",
context: "context-a",
weight: 0.004
})]);
var result = groupByContext(transformCorrelationData(response, 0.01));
expect(result.map(function (group) {
return group.context;
})).toEqual(["context-b", "context-a"]);
expect(result[1]).toMatchObject({
rowId: JSON.stringify(["context", "context-a"]),
kind: "context",
count: 2,
minWeight: 0.004
});
expect(result[1].children.map(function (item) {
return item.dimension;
})).toEqual(["c", "a"]);
});
it("groups thousands of rows without duplicating leaf objects", function () {
var items = Array.from({
length: 6000
}, function (_, index) {
return makeItem({
dimension: "dimension-".concat(index),
context: "context-".concat(index % 100),
weight: (index + 1) / 1000000
});
});
var flatData = transformCorrelationData(makeResponse(items), 1);
var result = groupByContext(flatData);
expect(result).toHaveLength(100);
expect(result.reduce(function (count, group) {
return count + group.children.length;
}, 0)).toBe(6000);
expect(result[0].children[0]).toBe(flatData[0]);
});
});