Création d'un nouveau type de champ pour formulaire dédié au stockage d'un dessin sur une image

Les sujets de cette catégorie concernent le développement du logiciel MedshakeEHR.
Avatar de l’utilisateur
Indelog
Administrateur
Messages : 71
Inscription : 10 juil. 2020, 10:06

Création d'un nouveau type de champ pour formulaire dédié au stockage d'un dessin sur une image

Message non lu par Indelog »

Certaines profession comme les ostéopathes et notamment avec Marsante et son projet de module dédié mais à mon avis pas que, ont besoin de pouvoir disposer de champ permettant effectuer des dessins libres par dessus des schémas (par exempla une représentation d'un squelette humain).

Je pense pour cela créer un nouveau type de champs dédié. Ce champ stockerai une image en base64 (donc pouvant être stocker sous forme de texte dans la table [li]data_object[/li]), l'image stocker serai issu d'un canevas js et dessiné directement par l'utilisateur (pour ce faire on pourrai envisage un plugin jQuery comme celui-ci https://github.com/yiom/sketchpad). J'ajoute aussi en pj du message une exemple un peut à l’arrache mais qui illustre ce que cela pourrai donner.

A noter que l'on ne stockerai pas dans bd l'image de fond mais uniquement de dessin fait par dessus. Le champ posséderai dans le formulaire une propriété dédié pour lui indiquer l'image de fond à utiliser.

Ce genre de champs possède un gros désavantage : l'image créé n'a pas de sens au niveau de la donnée (c'est juste un png), pour donner du sens au schémas il aurai mieux valus privilégier une méthode tel que celle utilisé dans le module Chiro. Cependant cette méthode est plus indiqué pour des cas plus simple ou il n'y a pas besoin de donner un sens à la donnée autres qu'un dessin perçu par l'utilisateur. Elle offre aussi plus de liberté a l'utilisateur pour représenter ce qu'il veut sur le dessin.

Ce type de champ pourrai être utilisé dans de multiples cas je pense notamment au module medTherm par exemple qui avait aussi besoin de schématiser un dessin avec des zones marquer dessus pour la prescription des soins (ce qui n'avait au final pas été fait car dispensable).

Je voudrai m’attaquer à la conception de ce champ qui rendrai Medshake encore plus polyvalent, cependant ya t'il des remarque particulière que je devais prendre en compte avant de me lancer ?
Pièces jointes
draw_shema_demo.zip
(360.49 Kio) Téléchargé 188 fois
DEMAREST Maxime (Indelog)
marsante
Messages : 175
Inscription : 25 juil. 2020, 18:42

Re: Création d'un nouveau type de champ pour formulaire dédié au stockage d'un dessin sur une image

Message non lu par marsante »

Les exemples dont je me suis inspiré si ça peut aider :

https://gist.github.com/MohammedEssehem ... 7dfee08f5f

https://projects.calebevans.me/jcanvas/ ... useEvents/

https://www.codicode.com/art/undo_and_r ... anvas.aspx

http://caimansys.com/painter/

Concernant le plugin, mon logiciel actuel encapsule le code canvas dans le plugin Jquery Boilerplate. A priori c'est juste pour permettre de le faire apparaître et disparaître de l'interface, plus que pour rajouter des fonctions de dessin de ce que j'ai pu en comprendre.
Avatar de l’utilisateur
Bertrand
Messages : 177
Inscription : 21 juil. 2020, 18:08
Localisation : Dans le grand bain
Contact :

Re: Création d'un nouveau type de champ pour formulaire dédié au stockage d'un dessin sur une image

Message non lu par Bertrand »

Je pense qu'il serait bien plus productif d'utiliser du SVG, soit avec un outil initialement prévu pour, soit par vectorisation secondaire du canvas, comme cela est le cas pour la signature sur tablette.
Stocker en base des données qui ne sont pas interprétables secondairement n'a à mon avis pas de sens. Autant les insérer dans le système de fichiers pour ne pas charger les datas essentielles qui elles sont structurées et parcourues intensément.

B.

MedShakeEHR : Le Logiciel Médical Modulaire Libre
http://www.medshake.app/

MedShake : communauté médicale bien fraîche (et un peu secouée) !
https://www.medshake.net/

Avatar de l’utilisateur
Indelog
Administrateur
Messages : 71
Inscription : 10 juil. 2020, 10:06

Re: Création d'un nouveau type de champ pour formulaire dédié au stockage d'un dessin sur une image

Message non lu par Indelog »

Pour la vectorisation du canvas ça me semble pas si simple. Dans l'idéal je pourrai peut être réutiliser les méthodes de jSignature mais j'en suis pas sûre. J'ai pas vraiment su trouver des libs adaptées à l’opération à par celle ci qui semble plus trop suivie : https://github.com/gliffy/canvas2svg si quelqu'un connais un moyen simple de faire l'opération je suis preneur.

Sinon apparemment pour ajouter un nouveau type de donnée :
  • Ajouter un enum pour formType dans la table data_types
  • Puis adapter msForm::_formBuilderBloc() pour ajouter les traitement spécifique au nouveau champ
Devrai suffire sauf si j'ai loupé des truc. Après y certain mécanisme de post traitement comme les validation que j'ai encore pris en compte, faudra que je vois.

Le fait que la donnée soit stocker dans un fichier plutôt que dans objets_data pose quelques petites difficultés notamment pour re-choper la valeur du champ via msForm::getPrevaluesForPatient(), il va falloir adapter le comportement pour le nouveau champ. Il va aussi falloir ignoré le nouveau champ dans msForm::formExtractDistinctTypes().

Je suis pas sure mais est ce que msStockage serai adapté pour stocker l'image produite pas le nouveau champ ?
DEMAREST Maxime (Indelog)
marsante
Messages : 175
Inscription : 25 juil. 2020, 18:42

Re: Création d'un nouveau type de champ pour formulaire dédié au stockage d'un dessin sur une image

Message non lu par marsante »

En attendant, j'étais passé à autre chose et à l'automatisation de l'installation. Mais comme j'ai tout fini, je reprends la réflexion sur le canvas.

En s'inspirant de cette organisation : https://openclassrooms.com/forum/sujet/ ... ire-en-bdd, au final est-ce qu'il ne suffirait pas de créer une ligne dans sqlInstall.sql pour ajouter les caractéristiques du formulaire. Donc un champ hidden ici :

Code : Tout sélectionner

SET @catID = (SELECT data_cat.id FROM data_cat WHERE data_cat.name='dataCsOsteo');
INSERT IGNORE INTO `data_types` (`groupe`, `name`, `placeholder`, `label`, `description`, `validationRules`, `validationErrorMsg`, `formType`, `formValues`, `module`, `cat`, `fromID`, `creationDate`, `durationLife`, `displayOrder`) VALUES
...
('medical', 'osteoSchema', 'Schémas', 'Schémas', 'Schémas', NULL, NULL, 'hidden', NULL, 'osteo', @catID, '1', '2019-01-01 00:00:00', '3600', '1'),
...
Toujours dans le sqlInstall.sql, ajouter la ligne dans le formulaire et le JavaScript (je vous fais grâce du code vu le nombre de lignes) ?

Puis probablement, adapter le HTML de

Code : Tout sélectionner

osteoConsult.html.twig
?

Placer le svg du background du canevas dans public_html/img ?

Comme le dessin sera enregistré dans un champ hidden et que le champ hidden est déjà connu de MedShakeEHR à priori pas besoin de retoucher à la base, mais que au module ?

Est-ce que la réflexion est bonne ou je sous-estime un truc ?

Deuxième question est ce qu'il y a besoin de charger jquery au début du script du formulaire, si oui comment ? J'ai regardé le js du module chiro est j'ai l'impression que les modules js sont appelés comme s'ils étaient déjà chargés ?

Au passage visiblement on peut se contenter de Jquery, il prend bien en charge les canvas et même le tactile (pas le cas dans l'exemple ci dessus).
Avatar de l’utilisateur
Bertrand
Messages : 177
Inscription : 21 juil. 2020, 18:08
Localisation : Dans le grand bain
Contact :

Re: Création d'un nouveau type de champ pour formulaire dédié au stockage d'un dessin sur une image

Message non lu par Bertrand »

Je n'ai pas tout suivi sur la question, mais il n'y a effectivement pas de raison que le stockage de données soit plus compliqué que l'ajout d'un type comme montré dans le bout de code sql.
Mais bon, je reste sur mon idée que stocker en bdd de la data non structurée ... bof boof.

Pour jquery, il est de toute façon chargé de base, c'est un pré requis de la version 4 de bootstrap.

B.

MedShakeEHR : Le Logiciel Médical Modulaire Libre
http://www.medshake.app/

MedShake : communauté médicale bien fraîche (et un peu secouée) !
https://www.medshake.net/

Avatar de l’utilisateur
Indelog
Administrateur
Messages : 71
Inscription : 10 juil. 2020, 10:06

Re: Création d'un nouveau type de champ pour formulaire dédié au stockage d'un dessin sur une image

Message non lu par Indelog »

Désolé j'ai pas donné de nouvelle sur le sujet depuis un moment faute de temps.

J'ai tout de même avancé de mon coté sur l'idée création d'un champs dédié aux schémas et finalement en essayant de répondre aux problèmes :
  • Le dessin qui soit stocké sous forme de SVG (non un base64 comme lors de la première) du coup comme ces histoires de vectorisation du canevas me semblaient prisent de têtes pour rien j'ai fait en sorte de dessiner directement du SVG (je me suis basé sur SVG.js mais sans utiliser le plugin de dessin) ce qui finalement est bien mieux : un SVG est directement rattaché aux DOM ce qui permet de faire facilement plein de truc cool.
  • Ne pas stocker des données "qui ne sont rattachés à aucune infos" et du coup j'ai ajouter une notion de "description" qui peut être ajouté aux différents éléments du dessin en exploitant les possibilitées offerte pas SVG notamment en groupant les élément dessinés dans une balise <g> pour les rattacher à une description donnée.
Voici une idée de ce que donnerai un tel champ avec ce prototype : https://c-medshakeehr.fr/proto-schemas/schemas.html

Dans la partie haute, le schémas et les différentes commande pour le dessin, dans la partis basse la gestion des descriptions. En fasse du titre "Description schémas" se trouve un bouton ajouter qui permet d'ajouter une description au schémas. Chaque description possède sa propre couleur (qui peut peut être modifié à n'importe quel moment) on compose ainsi un sorte de légende pour le schémas. Pour dessiner avec une description donnée il faut la sélectionné avec le bouton a gauche de la description. Le bouton à droite permet de la supprimer. Je l'ai pas implémenté mai je pense ajouter un moyen de mettre en évidence et d'afficher la description lié à un élément quant il est survolé par la souris ainsi qu'un bouton pour masquer ou afficher une description donnée.

Le champ "shémas" en lui même est donc composé de plusieurs éléments :
  • le SVG lui même (non fait dans le prototype mais il faudrait dumper le contenus du svg dans un input hidden à chaque modification du dessin pour qu'il soit envoyé avec le post du formulaire)
  • et les descriptions qui lui sont attachés
En base les descriptions auraient comment parentID le champ du SVG et ce dernier tout comme les autres champs conventionnel aurais comme parentID la consultation elle même. Ainsi les dessin sur les schémas ne sont plus de bêtes gribouillage mais sont rattachés à une donnés exploitables. Reste le problème du stockages des couleur rattaché à chaque description pour cela je propose de d'ajouter à la une colonnes "metadata" dans la table objets_data peut être de type JSON afin de pouvoir stocker toutes sortes de propriétés rattachés à un objet comme par exemple la couleur associé à une description de schémas (mais peut être d'autres ajouté comme si l’élément dessiné est visible ou on non, sélectionné, etc...) .

Pour l’implémentation du schémas lui même dans MedshakeEHR il faudra de toutes doutes façon crée un type de champ dédié aux schémas pour gérer les traitements spécifiques à la génération du formulaire et a sa sauvegarde.

Pour chaque champs "schémas" il faut lui associer une image de fond de taille variable à paramétrer par exemple à la conception du formulaire ou dans le data type associé (on peut ainsi crée autan de schémas différent que besoins), du coup je pense qu'il faudra aussi ajouter une page de config pour charger des background utilisables pour les schémas.

Coté js un schémas est géré pas sa propre class (implémenté sur mon prototype dans le fichier schemas.js) DrawSVG (que je vais sûrement renommer). Chaque instance de class intègre toutes les propriété d'un schémas ainsi il n'y a aucun problème pour faire coexister plusieurs schémas dans la même page.

J'ai crée un dépôt provisoire pour travailler sur le prototype js aux besoins : https://framagit.org/indelog/prototype-champ-sh-mas

A noter que ces fonctionnalités de dessin/description pourraient êtres utilisé aussi pour annoter des photos générer par phone-capture ou en fait tout ce que l'on veut, ou pourrait même envisager de générer des pdf avec le schémas accompagné de sa légende.

Bref ya moyen de faire quelques chose de complet et réutilisable dans de nombreux cas.

Avant d'aller plus loin et de commencer le travail pour intégrer tout ça dans MedshakeEHR avez vous des réflexion sur le prototype de champs schémas ou des suggestion d'amélioration ?
DEMAREST Maxime (Indelog)
marsante
Messages : 175
Inscription : 25 juil. 2020, 18:42

Re: Création d'un nouveau type de champ pour formulaire dédié au stockage d'un dessin sur une image

Message non lu par marsante »

Ça a l'air top par rapport aux premiers codes que j'avais trouvé. Je clone le projet, je regarde la doc du module et j'essaye de voir comment je peux aider d'ici dimanche. Pareil pour les remarques.
Avatar de l’utilisateur
Indelog
Administrateur
Messages : 71
Inscription : 10 juil. 2020, 10:06

Re: Création d'un nouveau type de champ pour formulaire dédié au stockage d'un dessin sur une image

Message non lu par Indelog »

Si vous l'utiliser en local il faudra faire un composer install à la racine du repo.

Je vais pas pouvoir me remettre dessus avant le week-end du 19/20 septembre mais j'y consacrerai mon week-end.

Sinon pour le js je pense repenser la class "DrawSVG" (et la renonner) pour lui faire décrire de manière plus complète le concept de champs schémas (un dessin SVG sur un font avec diverses infos rattaché aux élément dessiné comme les déscriptions).

Pour le stockage dans le champs "value" de la table "objets_data" on peut aussi envisager de donner un format précis au texte stocké (par exemple du json), le champs pourais ainsi embarqué directement le dessin SVG, les descriptions et d'autres truc aux quel j'ai pas pensés. Cela nous éviterais de créer des datas filles du champs lui même pour y stoker les descriptions associés (ou autres). Concrètement le truc stocké ressemblerait à ça :

Code : Tout sélectionner

{
	"descriptions": [
		{"num": 1, "color": "#FF0000", "text": "Ma description 1"},
		{"num": 2, "color": "#00FF00", "text": "Ma description 2"}
	],
	"autres_eventuel_propriete_que_on_ajouter": "value",
	"svg": "<svg>....</svg>"
}
Les avantages à procéder comme ceci sont :
  • Stockage simple et facile
  • Format facile à faire évoluer et adapter
Le gros inconvegniant et qu'il devient difficile de faire des recherche sur les données stockés dans un champs schémas (ce qui est plus simple a faire avec un objets_data fils du champs schémas lui même), le champs étant au niveaux SQL un champs type texte et non JSON.

Eratum

Je vient découvrir que Mysql gère très bien les données de type JSON y compris si elles sont stockés dans un champ de type texte : https://dev.mysql.com/doc/refman/8.0/en ... tions.html.

Exemple :

Code : Tout sélectionner

create table toto(id INT, value text, primary key(id)) ;
use toto;
insert into toto values (1, '{"p1":"A", "p2":"B"}'), (2, '{"t1":"A", "t2":"C"}');
select json_extract(value, "$.t1") from toto;
select * from toto where json_extract(value, "$.t2") = 'C';
C'est trop bien. Par contre je suis pas sure que les perfs soient génial mais mais on devait pouvoir facilement faire des recherches sur des propriétés associés aux champs schémas. Du coups c'est beaucoup plus simple de tout mettre sous format JSON dans l'objet data associé au fields plutôt que d’attacher les divers élément du champs dans des objets_data fils du champs.
DEMAREST Maxime (Indelog)
Répondre