@neo4j-ndl/react
Version:
React implementation of Neo4j Design System
167 lines • 6.69 kB
JavaScript
;
/**
*
* Copyright (c) "Neo4j"
* Neo4j Sweden AB [http://neo4j.com]
*
* This file is part of Neo4j.
*
* Neo4j is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.captionPriorityOrder = exports.NO_LABEL_FALLBACK_COLOR = exports.DEFAULT_REL_COLOR = void 0;
exports.getDefaultCaptionKey = getDefaultCaptionKey;
exports.mapToNvlGraph = mapToNvlGraph;
const word_color_1 = require("@neo4j-devtools/word-color");
const base_1 = require("@neo4j-ndl/base");
exports.DEFAULT_REL_COLOR = base_1.tokens.colors.neutral['40'];
exports.NO_LABEL_FALLBACK_COLOR = base_1.tokens.colors.neutral['40'];
const sortAlphabetically = (a = '', b = '') => a.toLowerCase().localeCompare(b.toLowerCase());
function getMostCommonColor(colors) {
var _a;
const [firstColor] = colors;
if (firstColor === undefined) {
return exports.NO_LABEL_FALLBACK_COLOR;
}
const colorCounts = {};
for (const color of colors) {
colorCounts[color] = ((_a = colorCounts[color]) !== null && _a !== void 0 ? _a : 0) + 1;
}
let maxCount = 0;
let mostCommonColor = firstColor;
for (const [color, colorCount] of Object.entries(colorCounts)) {
if (colorCount > maxCount) {
maxCount = colorCount;
mostCommonColor = color;
}
}
return mostCommonColor;
}
function transformToItemMetada(arg) {
return Object.entries(arg).reduce((acc, [label, colors]) => {
acc[label] = {
mostCommonColor: getMostCommonColor(colors),
totalCount: colors.length,
};
return acc;
}, {});
}
exports.captionPriorityOrder = [
/^name$/i,
/^title$/i,
/^label$/i,
/name$/i,
/description$/i,
/^.+/,
];
function getDefaultCaptionKey(options) {
const captionKeys = options
.filter((option) => option.type === 'property')
.map((option) => option.captionKey);
for (const regex of exports.captionPriorityOrder) {
const matchingKey = captionKeys.find((key) => regex.test(key));
if (matchingKey !== undefined) {
return {
captionKey: matchingKey,
type: 'property',
};
}
}
const typeOption = options.find((option) => option.type === 'type');
if (typeOption) {
return typeOption;
}
return options.find((option) => option.type === 'id');
}
const getDefaultNodeCaption = (item) => {
const options = Object.keys(item.properties).map((property) => ({
captionKey: property,
type: 'property',
}));
options.push({ type: 'id' }, { type: 'type' });
const defaultCaptionKey = getDefaultCaptionKey(options);
if ((defaultCaptionKey === null || defaultCaptionKey === void 0 ? void 0 : defaultCaptionKey.type) === 'property') {
const caption = item.properties[defaultCaptionKey.captionKey];
if (caption !== undefined) {
// remove quotes from string
if (caption.type === 'string') {
return [{ value: caption.stringified.slice(1, -1) }];
}
return [{ value: caption.stringified }];
}
}
const [firstLabel] = item.labels;
if ((defaultCaptionKey === null || defaultCaptionKey === void 0 ? void 0 : defaultCaptionKey.type) === 'type' && firstLabel !== undefined) {
return [{ value: firstLabel }];
}
return [{ value: item.id }];
};
// Properties can be huge, so we split them out into a separate lookup table
// to prevent them from making the physics slow
// here we also apply default colors & captions to nodes and relationships
// and sample colors for the sidepanel
// in the future we'll apply styling here as well
function mapToNvlGraph(rawNodes, rawRels) {
const labelColorPairs = {};
const typeColorPairs = {};
const nodeData = {};
const relData = {};
const nodes = rawNodes.map((node) => {
var _a;
const [firstLabel] = node.labels;
const newNode = Object.assign(Object.assign({ captions: getDefaultNodeCaption(node), color: (_a = node.color) !== null && _a !== void 0 ? _a : (firstLabel === undefined
? exports.NO_LABEL_FALLBACK_COLOR
: (0, word_color_1.calculateDefaultNodeColors)(firstLabel).backgroundColor) }, node), { labels: undefined, properties: undefined });
nodeData[node.id] = {
color: newNode.color,
id: node.id,
labelsSorted: [...node.labels].sort(sortAlphabetically),
properties: node.properties,
};
node.labels.forEach((label) => {
var _a;
labelColorPairs[label] = [
...((_a = labelColorPairs[label]) !== null && _a !== void 0 ? _a : []),
newNode.color,
];
});
return newNode;
});
const rels = rawRels.map((rel) => {
var _a, _b, _c;
relData[rel.id] = {
color: (_a = rel.color) !== null && _a !== void 0 ? _a : exports.DEFAULT_REL_COLOR,
id: rel.id,
properties: rel.properties,
type: rel.type,
};
typeColorPairs[rel.type] = [
...((_b = typeColorPairs[rel.type]) !== null && _b !== void 0 ? _b : []),
(_c = rel.color) !== null && _c !== void 0 ? _c : exports.DEFAULT_REL_COLOR,
];
return Object.assign(Object.assign({ captions: [{ value: rel.type }], color: exports.DEFAULT_REL_COLOR }, rel), { properties: undefined, type: undefined });
});
const labelMetaData = transformToItemMetada(labelColorPairs);
const typeMetaData = transformToItemMetada(typeColorPairs);
const dataLookupTable = {
labelMetaData,
labels: Object.keys(labelMetaData).sort((a, b) => sortAlphabetically(a, b)),
nodes: nodeData,
relationships: relData,
typeMetaData,
types: Object.keys(typeMetaData).sort((a, b) => sortAlphabetically(a, b)),
};
return { dataLookupTable, nodes, rels };
}
//# sourceMappingURL=map-to-nvl-graph.js.map