Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion src/charts/CytoViz/CytoViz.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ export const CytoViz = (props) => {
cytoscapeStylesheet,
defaultSettings,
elements,
elementsMetadata,
error,
extraLayouts,
getElementDetails,
Expand Down Expand Up @@ -81,7 +82,17 @@ export const CytoViz = (props) => {
let getElementDetailsCallback = getElementDetails;
if (!getElementDetailsCallback) {
// eslint-disable-next-line react/display-name
getElementDetailsCallback = (element) => <ElementData data={element.data()} labels={labels_.elementData} />;
getElementDetailsCallback = (element) => {
const elementType = element.classes && element.classes()?.[0];
return (
<ElementData
data={element.data()}
labels={labels_.elementData}
metadata={elementsMetadata}
type={elementType}
/>
);
};
getElementDetailsCallback.displayName = 'ElementData';
}

Expand Down Expand Up @@ -714,6 +725,18 @@ CytoViz.propTypes = {
* Array of cytoscape elements to display
*/
elements: PropTypes.array.isRequired,
/**
* Optional array of metadata for cytoscape elements. Currently, it only takes an attributesOrder property to force
* the order of attributes when entity details are displayed.
* Expected format example:
* {
* attributesOrder: {
* nodes: { nodeType1: ['someImportantAttribute', 'attribute1', 'attribute2', 'attribute3'] },
* edges: { edgeType1: ['attributeA', 'attributeB']}},
* }
* }
*/
elementsMetadata: PropTypes.object,
/**
* Object of extra layouts to register in cytoscape. The keys of this object must be the layout names, and the values
must be the extension object to provide to cytoscape.use(...). If you want to add a default cytoscape layout
Expand Down Expand Up @@ -829,6 +852,7 @@ CytoViz.defaultProps = {
showStats: false,
spacingFactor: 1,
},
elementsMetadata: {},
extraLayouts: {},
groups: {},
labels: DEFAULT_LABELS,
Expand Down
25 changes: 20 additions & 5 deletions src/charts/CytoViz/components/ElementData/ElementData.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,26 @@ const _generateAttributeDetails = (classes, labels, attributeName, attributeValu
}
};

const getSortedAttributeNames = (expectedKeys, allKeys) => {
// Start with expected keys in desired order
const sortedKeys = expectedKeys.filter((key) => allKeys.includes(key));
allKeys.filter((key) => !expectedKeys.includes(key)).forEach((key) => sortedKeys.push(key)); // Add unknown keys
return sortedKeys;
};

const ElementData = (props) => {
const classes = useStyles();
const { data, labels } = props;
if (!data) {
return labels.noData;
}
const { data, labels, metadata, type } = props;
if (!data) return labels.noData;

const attributesOrderConfig = metadata?.attributesOrder;
const desiredAttributesOrder = type && (attributesOrderConfig?.nodes?.[type] ?? attributesOrderConfig?.edges?.[type]);

let sortedElementAttributeNames = Object.keys(data);
if (desiredAttributesOrder != null)
sortedElementAttributeNames = getSortedAttributeNames(desiredAttributesOrder, Object.keys(data));

let filteredElementAttributes = Object.keys(data)
let filteredElementAttributes = sortedElementAttributeNames
.map((key) => _generateAttributeDetails(classes, labels, key, data[key]))
.filter((el) => el !== null);
if (filteredElementAttributes.length === 0) {
Expand All @@ -89,10 +101,13 @@ const ElementData = (props) => {
ElementData.propTypes = {
data: PropTypes.object,
labels: PropTypes.object,
metadata: PropTypes.object,
type: PropTypes.string,
};

ElementData.defaultProps = {
data: PropTypes.object,
metadata: {},
labels: {
attributes: {},
dictKey: 'Key',
Expand Down