import React from 'react'; import PropTypes from 'prop-types'; import Graph from './Graph.js'; import {useAsync} from '../util.js'; import {Term, termTypes} from '../data/model.js'; import {symptomsSubgraph} from '../data/mock'; /** * Graphe de maladies et symptômes. * * @prop terms Termes à afficher. * @prop query Ensemble de termes recherchés par l’utilisateur. * @prop setQuery Fonction de rappel pour ajouter de nouveaux termes de * recherche. */ const DiseaseGraph = ({terms, query, setQuery}) => { const {nodes, edges} = useAsync({ nodes: {}, edges: [] }, symptomsSubgraph, terms); /** * Rendu d’un nœud du graphe. * * @param id Identifiant du nœud à afficher. */ const render = id => { const term = nodes[id]; const isInQuery = query.some(({id: termId}) => termId === id); const isDisease = nodes[id].types.includes(termTypes.disease); return ( {nodes[id].name} ); }; /** * Gère le clic sur un nœud du graphe. * * @param id Identifiant du nœud cliqué. * @param ev Événement DOM décrivant le clic. */ const handleNodeClick = (id, ev) => { const term = nodes[id]; const queryIndex = query.findIndex(({id: termId}) => termId === id); if (!ev.ctrlKey) { // Clic normal : Ouverture de la ressource window.open(term.url, '_blank'); } else if (queryIndex >= 0) { // Ctrl-clic : Retrait d’un terme déjà dans la requête setQuery([ ...query.slice(0, queryIndex), ...query.slice(queryIndex + 1) ]); } else { // Ctrl-clic : Ajout d’un nouveau terme dans la requête setQuery(query.concat([term])); } }; return ( ); }; DiseaseGraph.propTypes = { terms: PropTypes.arrayOf(Term).isRequired, query: PropTypes.arrayOf(Term).isRequired, setQuery: PropTypes.func.isRequired, }; export default DiseaseGraph;