Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#SDSV-40 - Extract sparc:performances from turtle file and render in Graph Viewer #239

Open
wants to merge 4 commits into
base: development
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
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
Next Next commit
#SDSV-40 - Extract sparc:performances from turtle file and render in …
…Graph Viewer
  • Loading branch information
jrmartin committed Feb 17, 2025
commit 46bfec9e401da0638b85ef4751302a29ad148c34
9 changes: 8 additions & 1 deletion src/components/DatasetsListViewer/DatasetsListSplinter.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,13 @@ class Splinter {
let sparcType = type.type.split(this.types.sparc.iri.id).pop();
typeFound.type = typesModel.sparc[sparcType].type;
typeFound.length = typesModel.sparc[sparcType].length;
} else if ( type.type === this.types.owl.iri.id + "Performance") {
for (const rdfType in this.types) {
if ((node.id.includes(this.types[rdfType].iri.id)) && (this.types[rdfType].iri.id.length > typeFound.length) && (typesModel.NamedIndividual[String(this.types[rdfType].type)] !== undefined)) {
typeFound.type = typesModel.NamedIndividual[String(this.types[rdfType].type)].type;
typeFound.length = this.types[rdfType].iri.id.length;
}
}
}
}
return typeFound.type;
Expand Down Expand Up @@ -300,7 +307,7 @@ class Splinter {

identify_childless_parents() {
this.forced_nodes.forEach((node, index, array) => {
if ((node.type === rdfTypes.Sample.key || node.type === rdfTypes.Subject.key) && (node.children_counter === 0)) {
if ((node.type === rdfTypes.Sample.key || node.type === rdfTypes.Subject.key || node.type === rdfTypes.Performance.key) && (node.children_counter === 0)) {
node.img.src = "./images/graph/question_mark.svg"
}
});
Expand Down
6 changes: 3 additions & 3 deletions src/components/GraphViewer/GraphViewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ const GraphViewer = (props) => {
};

const handleNodeLeftClick = (node, event) => {
if ( node.type === rdfTypes.Subject.key || node.type === rdfTypes.Sample.key || node.type === rdfTypes.Collection.key ) {
if ( node.type === rdfTypes.Subject.key || node.type === rdfTypes.Performance.key || node.type === rdfTypes.Sample.key || node.type === rdfTypes.Collection.key ) {
collapseSubLevels(node, node.collapsed, { links : 0 });
node.collapsed = !node.collapsed;
let updatedData = getPrunedTree(props.graph_id, selectedLayout.layout);
Expand Down Expand Up @@ -242,14 +242,14 @@ const GraphViewer = (props) => {
}

if ( prevNode && nodeSelected.collapsed && nodeClickSource === "TREE") {
if ( prevNode.type == rdfTypes.Subject.key || prevNode.type == rdfTypes.Sample.key ||
if ( prevNode.type == rdfTypes.Subject.key || prevNode.type == rdfTypes.Sample.key || prevNode.type == rdfTypes.Performance.key ||
prevNode.type == rdfTypes.Collection.key ) {
prevNode.collapsed = false;
collapseSubLevels(prevNode, false, { links : 0 });
let updatedData = getPrunedTree(props.graph_id, selectedLayout.layout);
setData(updatedData);
}
if ( node.parent?.type == rdfTypes.Subject.key || node.parent?.type == rdfTypes.Sample.key ||
if ( node.parent?.type == rdfTypes.Subject.key || node.parent?.type == rdfTypes.Sample.key || node.parent?.type == rdfTypes.Performance.key ||
node.parent?.type == rdfTypes.Collection.key ) {
collapseSubLevels(node.parent, true, { links : 0 });
let updatedData = getPrunedTree(props.graph_id, selectedLayout.layout);
Expand Down
74 changes: 74 additions & 0 deletions src/components/NodeDetailView/Details/PerformanceDetails.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import {
Box,
Divider,
Typography,
} from "@material-ui/core";
import SimpleLinkedChip from './Views/SimpleLinkedChip';
import SimpleLabelValue from './Views/SimpleLabelValue';
import Links from './Views/Links';
import { detailsLabel } from '../../../constants';
import { isValidUrl } from './utils';
import { useSelector } from 'react-redux'

const PerformanceDetails = (props) => {
const { node } = props;

const performancePropertiesModel = useSelector(state => state.sdsState.metadata_model.performance);

const getGroupNode = (groupName, node)=> {
let n = node.graph_node.parent;
let match = false;
while ( n && !match ) {
if ( n.name === groupName ) {
match = true;
} else {
n = n.parent;
}
}

return n;
}

return (
<Box id={node?.graph_node?.id + detailsLabel}>
<Divider />
<Box className="tab-content">
<SimpleLabelValue label={""} value={""} heading={"Performance Details"} />

{performancePropertiesModel?.map( property => {
if ( property.visible ){
const propValue = node.graph_node.attributes?.[property.property]?.[0];
if ( property.isGroup ){
return (<Box className="tab-content-row">
<Typography component="label">{property.label}</Typography>
<SimpleLinkedChip chips={[{ value : node.graph_node.attributes[property.property]}]} node={getGroupNode(node.graph_node.attributes[property.property]?.[0], node)} />
</Box>)
}

else if ( isValidUrl(propValue) ){
return (<Box className="tab-content-row">
<Typography component="label">{property.label}</Typography>
<Links key={`detail_links_dataset`} href={propValue} title={property.label + " Link"} />
</Box>)
}

else if ( typeof propValue === "object" ){
return (<Box className="tab-content-row">
<Typography component="label">{property.label}</Typography>
<SimpleLinkedChip chips={node.graph_node.attributes[property.property]} />
</Box>)
}

else if ( typeof propValue === "string" ){
return (<SimpleLabelValue label={property.label} value={propValue} />)
}

return (<> </>)
}
})}
</Box>
</Box>
);
};

export default PerformanceDetails;
3 changes: 2 additions & 1 deletion src/components/NodeDetailView/NodeDetailView.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import NodeFooter from "./Footers/Footer";
import DetailsFactory from './factory';
import Breadcrumbs from "./Details/Views/Breadcrumbs";
import { IconButton, Tooltip } from '@material-ui/core';
import { subject_key, protocols_key, contributors_key } from '../../constants';
import { subject_key, protocols_key, contributors_key, performances_key } from '../../constants';
import {TuneRounded} from "@material-ui/icons";
import { useSelector, useDispatch } from 'react-redux'
import { toggleSettingsPanelVisibility } from '../../redux/actions';
Expand Down Expand Up @@ -41,6 +41,7 @@ const NodeDetailView = (props) => {
tree_node: graph_node.tree_reference
}
if (new_node?.graph_node?.id !== subject_key
&& new_node?.graph_node?.id !== performances_key
&& new_node?.graph_node?.id !== contributors_key
&& new_node?.graph_node?.id !== protocols_key) {
links.pages.push({
Expand Down
43 changes: 43 additions & 0 deletions src/components/NodeDetailView/factory.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import SampleDetails from './Details/SampleDetails';
import DatasetDetails from './Details/DatasetDetails';
import SubjectDetails from './Details/SubjectDetails';
import ProtocolDetails from './Details/ProtocolDetails';
import PerformanceDetails from './Details/PerformanceDetails';
import GroupDetails from './Details/GroupDetails';
import CollectionDetails from './Details/CollectionDetails'
import Settings from "./settings/Settings"
Expand Down Expand Up @@ -43,6 +44,9 @@ var DetailsFactory = function () {
case rdfTypes.Subject.key:
details = new Subject(node);
break;
case rdfTypes.Performance.key:
details = new Performance(node);
break;
case rdfTypes.File.key:
details = new File(node);
break;
Expand Down Expand Up @@ -283,6 +287,45 @@ const Subject = function (node) {
return nodeDetail;
};

const Performance = function (node) {
const nodeDetail = {
node: node
};
nodeDetail.getHeader = () => {
return (
<>
<CollectionHeader node={node} />
</>
)
};

nodeDetail.getDetail = () => {
return (
<>
<PerformanceDetails node={node} />
</>
)
};

nodeDetail.getAll = () => {
return (
<>
<CollectionHeader node={node} />
<PerformanceDetails node={node} />
</>
)
}

nodeDetail.getSettings = () => {
return (
<>
<Settings node={node} />
</>
)
}
return nodeDetail;
};

const File = function (node) {
const nodeDetail = {
node: node
Expand Down
1 change: 1 addition & 0 deletions src/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export const NODES = ["dataset", "nifti", "volume", "matlab"];
export const detailsLabel = "_details";

export const subject_key = "all_subjects";
export const performances_key = "all_performances";
export const protocols_key = "all_protocols";
export const contributors_key = "all_contributors";

Expand Down
1 change: 1 addition & 0 deletions src/redux/initialState.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const savedMetadataModel = localStorage.getItem("metadata_model");
const initialMetadataModel = savedMetadataModel ? JSON.parse(savedMetadataModel) : {
dataset: [...rdfTypes.Dataset.properties],
subject: [...rdfTypes.Subject.properties],
performance: [...rdfTypes.Performance.properties],
sample: [...rdfTypes.Sample.properties],
collection : [...rdfTypes.Collection.properties],
group: [...rdfTypes.Group.properties],
Expand Down
47 changes: 41 additions & 6 deletions src/utils/Splinter.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import config from './../config/app.json';

import {
subject_key,
performances_key,
protocols_key,
contributors_key, SUBJECTS_LEVEL, PROTOCOLS_LEVEL, CRONTRIBUTORS_LEVEL
} from '../constants';
Expand Down Expand Up @@ -348,6 +349,8 @@ class Splinter {
let sparcType = type.type.split(this.types.sparc.iri.id).pop();
typeFound.type = typesModel.sparc[sparcType].type;
typeFound.length = typesModel.sparc[sparcType].length;
} else if ( type.type.includes("/sparc/Performance")) {
typeFound.type = typesModel.NamedIndividual.performance.type;
}
}
return typeFound.type;
Expand Down Expand Up @@ -531,8 +534,8 @@ class Splinter {
return dataset_node;
}

organise_subjects(target_node, link, groups){
let parent = this.nodes.get(subject_key);
organise_subjects(target_node, link, groups, k, type){
let parent = this.nodes.get(k);
let keys = Object.keys(config.groups.order);
keys.forEach( key => {
let group = config.groups.order[key];
Expand Down Expand Up @@ -587,7 +590,7 @@ class Splinter {
target_node.id = parent.id + target_node.name;
target_node.parent = parent;
target_node.childLinks = [];
target_node.collapsed = target_node.type === typesModel.NamedIndividual.subject.type;
target_node.collapsed = target_node.type === type;
this.nodes.set(target_node.id, target_node);
}

Expand All @@ -608,7 +611,7 @@ class Splinter {
childLinks : []
};
if (this.nodes.get(subject_key) === undefined) {
this.nodes.set(subject_key, this.factory.createNode(subjects));
this.nodes.set(subject_key, this.factory.createNode(subjects, this.types));
const img = new Image();
img.src = "./images/graph/group.svg";
subjects.img = img;
Expand All @@ -620,6 +623,32 @@ class Splinter {
console.error("The subjects node already exists!");
}

const performances = {
id: performances_key,
name: "Performances",
type: rdfTypes.Performance.key,
properties: [],
parent : parent,
proxies: [],
level: SUBJECTS_LEVEL,
tree_reference: null,
children_counter: 0,
collapsed : false,
childLinks : []
};
if (this.nodes.get(performances_key) === undefined) {
this.nodes.set(performances_key, this.factory.createNode(performances, this.types));
const img = new Image();
img.src = "./images/graph/group.svg";
performances.img = img;
this.edges.push({
source: id,
target: performances.id
})
} else {
console.error("The performances node already exists!");
}

const protocols = {
id: protocols_key,
name: "Protocols",
Expand Down Expand Up @@ -681,7 +710,9 @@ class Splinter {
}
let target_node = this.nodes.get(link.target);
if (link.source === id && link.target !== subject_key && target_node.type === rdfTypes.Subject.key) {
this.organise_subjects(target_node, link, groups);
this.organise_subjects(target_node, link, groups, subject_key, typesModel.NamedIndividual.subject.type);
} else if (link.source === id && link.target !== performances_key && target_node.type === rdfTypes.Performance.key) {
this.organise_subjects(target_node, link, groups, performances_key, typesModel.NamedIndividual.performance.type);
} else if (link.source === id && link.target !== contributors_key && target_node.type === rdfTypes.Person.key) {
link.source = contributors_key;
target_node.level = contributors.level + 1;
Expand All @@ -707,7 +738,7 @@ class Splinter {
return link;
}).filter(link => {
let target_node = this.nodes.get(link.target);
if ((link.source === id && (target_node.type !== rdfTypes.Award.key) && (link.target !== contributors_key && link.target !== subject_key && link.target !== protocols_key))) {
if ((link.source === id && (target_node.type !== rdfTypes.Award.key) && (link.target !== contributors_key && link.target !== subject_key && link.target !== performances_key && link.target !== protocols_key))) {
return false;
}
return true;
Expand Down Expand Up @@ -935,6 +966,10 @@ class Splinter {
newName = splitName[0] + "/" + newName
}

if ( value.type === rdfTypes.Performance.key && value.attributes?.localId?.[0] == splitName[splitName.length - 1] ) {
newName = splitName[0] + "/" + newName
}

let parentNode = value;
let newNode = this.buildFolder(jsonNode, newName, parentNode);

Expand Down
Loading
Loading