UNPKG

@formant/ava

Version:

A framework for automated visual analytics.

189 lines (188 loc) 8.78 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var analysis_1 = require("../../analysis"); var graph_1 = require("../../analysis/graph"); var field_1 = require("../../analysis/field"); var utils_1 = require("../../utils"); var dataFrame_1 = tslib_1.__importDefault(require("../field/dataFrame")); var utils_2 = require("./utils"); /* eslint-disable no-param-reassign */ function parseTreeNode(data, extra) { var nodes = []; var links = []; var childrenKey = (extra === null || extra === void 0 ? void 0 : extra.childrenKey) || 'children'; var parseTree = function (treeNode) { var children = treeNode[childrenKey] || []; delete treeNode[childrenKey]; nodes === null || nodes === void 0 ? void 0 : nodes.push(treeNode); for (var i = 0; i < children.length; i += 1) { var item = children[i]; links === null || links === void 0 ? void 0 : links.push({ source: treeNode.id, target: item.id, }); parseTree(item); } }; parseTree(data); return { nodes: nodes, links: links }; } /** * @param data link array */ function parseArray(data, extra) { var _a = tslib_1.__read(data, 1), data0 = _a[0]; (0, utils_1.assert)((0, utils_1.isObject)(data0), 'Data is unable transform to graph'); var sourceKey = (extra === null || extra === void 0 ? void 0 : extra.sourceKey) || ('source' in data0 && 'source') || ('from' in data0 && 'from'); var targetKey = (extra === null || extra === void 0 ? void 0 : extra.targetKey) || ('target' in data0 && 'target') || ('to' in data0 && 'to'); var childrenKey = (extra === null || extra === void 0 ? void 0 : extra.childrenKey) || ('children' in data0 && 'children') || ('to' in data0 && 'to'); (0, utils_1.assert)(sourceKey || targetKey || childrenKey, 'Data is unable transform to graph'); var nodes = []; var links = []; var _b = data0, _c = sourceKey, source = _b[_c], _d = targetKey, target = _b[_d], _e = childrenKey, children = _b[_e]; if ((0, utils_1.isBasicType)(source) && (0, utils_1.isBasicType)(target)) { var _loop_1 = function (i) { var link = data[i]; var _g = link, _h = sourceKey, source_1 = _g[_h], _j = targetKey, target_1 = _g[_j]; if (nodes.findIndex(function (n) { return n.id === source_1; }) === -1) { nodes.push({ id: source_1 }); } if (nodes.findIndex(function (n) { return n.id === target_1; }) === -1) { nodes.push({ id: target_1 }); } var formatLink = tslib_1.__assign(tslib_1.__assign({}, link), { source: source_1, target: target_1 }); links.push(formatLink); }; for (var i = 0; i < data.length; i += 1) { _loop_1(i); } } else if ((0, utils_1.isArray)(children)) { // try to parse the array as multiple trees for (var i = 0; i < data.length; i += 1) { var tree = data[i]; var _f = parseTreeNode(tree, extra), subNodes = _f.nodes, subLinks = _f.links; var _loop_2 = function (i_1) { var node = subNodes[i_1]; var repeatNode = nodes.find(function (n) { return n.id === node.id; }); if (repeatNode) { repeatNode = tslib_1.__assign(tslib_1.__assign({}, node), repeatNode); } else { nodes.push(node); } }; for (var i_1 = 0; i_1 < subNodes.length; i_1 += 1) { _loop_2(i_1); } links.push.apply(links, tslib_1.__spreadArray([], tslib_1.__read(subLinks), false)); } } return { nodes: nodes, links: links }; } function isNodeArray(arr) { if (!(0, utils_1.isArray)(arr) || arr.length <= 1) return false; var nodeIdInfo = (0, analysis_1.analyzeField)(arr.map(function (node) { return node.id; })); return (0, field_1.isUnique)(nodeIdInfo); } function isValidNodeLinks(nodes, links) { if (!(0, utils_1.isArray)(links) || !isNodeArray(nodes) || links.length <= 1) return false; var _loop_3 = function (i) { var link = links[i]; var source = link.source, target = link.target; var hasSourceNode = nodes.findIndex(function (item) { return item.id === source; }); var hasTargetNode = nodes.findIndex(function (item) { return item.id === target; }); if (!(hasSourceNode > -1 && hasTargetNode > -1)) { return { value: false }; } }; for (var i = 0; i < links.length; i += 1) { var state_1 = _loop_3(i); if (typeof state_1 === "object") return state_1.value; } return true; } // TODO: The automatic parsing function has not been completed yet, for now, the GraphData constructor only accepts input data in several specified formats (see type GraphInput) var GraphData = /** @class */ (function () { function GraphData(data, extra) { this.data = { nodes: [], links: [], }; this.extra = extra; var _a = this.autoParse(data, extra), nodes = _a.nodes, links = _a.links; (0, utils_1.assert)(isValidNodeLinks(nodes, links), 'Data is unable transform to graph'); this.data = { nodes: nodes.map(function (node) { return (0, utils_2.flatObject)(node); }), links: links.map(function (link) { return (0, utils_2.flatObject)(link); }), }; } GraphData.prototype.autoParse = function (data, extra) { var nodes; var links; (0, utils_1.assert)((0, utils_1.isArray)(data) || (0, utils_1.isObject)(data), 'Data is unable transform to graph'); // try parse data as link array or multiple trees if ((0, utils_1.isArray)(data)) { var parsedData = parseArray(data, extra); nodes = parsedData.nodes; links = parsedData.links; } // if passed data tyoe is object if ((0, utils_1.isObject)(data)) { if ((extra === null || extra === void 0 ? void 0 : extra.nodeKey) && (extra === null || extra === void 0 ? void 0 : extra.linkKey)) { nodes = data[extra.nodeKey]; links = data[extra.linkKey]; } else if ((extra === null || extra === void 0 ? void 0 : extra.childrenKey) || 'children' in data) { var parsedTree = parseTreeNode(data, extra); nodes = parsedTree.nodes; links = parsedTree.links; } else { var nodeKey = 'nodes' in data && 'nodes'; var linkKey = ('links' in data && 'links') || ('edges' in data && 'edges'); nodes = data[nodeKey]; links = data[linkKey]; } } return { nodes: nodes, links: links }; }; GraphData.prototype.getNodeFrame = function () { var _a, _b; var extra = { indexes: (_a = this.extra) === null || _a === void 0 ? void 0 : _a.nodeIndexes, columns: (_b = this.extra) === null || _b === void 0 ? void 0 : _b.nodeColumns, }; return new dataFrame_1.default(this.data.nodes, extra); }; GraphData.prototype.getLinkFrame = function () { var _a, _b; var extra = { indexes: (_a = this.extra) === null || _a === void 0 ? void 0 : _a.linkIndexes, columns: (_b = this.extra) === null || _b === void 0 ? void 0 : _b.linkColumns, }; return new dataFrame_1.default(this.data.links, extra); }; /** * Get statistics. */ GraphData.prototype.info = function () { var _a = this.data, nodes = _a.nodes, links = _a.links; // calc fields statistics and structural statistics var graphStructFeats = (0, graph_1.getAllStructFeats)(nodes, links); var _b = (0, graph_1.getNodeFields)(nodes), nodeFields = _b.nodeFields, nodeFieldNames = _b.nodeFieldNames; var _c = (0, graph_1.getLinkFields)(links), linkFields = _c.linkFields, linkFieldNames = _c.linkFieldNames; var nodeFieldsInfo = (0, graph_1.getAllFieldsInfo)(nodeFields, nodeFieldNames); var linkFieldsInfo = (0, graph_1.getAllFieldsInfo)(linkFields, linkFieldNames); var getClusterField = (0, graph_1.clusterNodes)(nodes, nodeFieldsInfo, links); nodeFieldsInfo.push(getClusterField); var graphProps = tslib_1.__assign({ nodeFieldsInfo: nodeFieldsInfo, linkFieldsInfo: linkFieldsInfo }, graphStructFeats); return graphProps; }; return GraphData; }()); exports.default = GraphData;