Forum |  HardWare.fr | News | Articles | PC | Prix | S'identifier | S'inscrire | Aide | Shop Recherche
2015 connectés 

  FORUM HardWare.fr
  Programmation
  PHP

  Affichage évènement de plusieurs jours sur un calendrier

 



 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Affichage évènement de plusieurs jours sur un calendrier

n°2316765
depart
Posté le 10-06-2018 à 14:09:49  profilanswer
 

Je bosse sur le principe suivant :
un calendrier, avec un affichage par semaine (lundi-dimanche) et dessus j'ai des évènements (des rendez-vous en général) à afficher.
Techniquement j'affiche ma semaine, divisée en quarts d'heures (ou autre subdivision) et pour chaque quart d'heure je regarde si j'ai un rdv qui commence à cette heure.
Si oui, pour l'afficher je créé un div qui a pour hauteur la durée en quarts d'heures multipliée par la hauteur d'un quart d'heure.
Exemple : rdv de 14h à 15h30, si un quart d'heure fait 30px sur mon affichage, je créé un div de 6x30 = 180 px) qui est positionné à partir du coin haut/gauche de la tranche 14h00.
 
En bdd (mysql) j'ai une table du genre :
rdv_id, date_heure_debut, date_heure_fin, description...
Pour l'instant pour chaque "vue" de type semaine, je récupère la liste des rdv dont la date_heure_debut est entre le début et la fin de la semaine.
Ensuite pour "l'affichage",  pour chaque quart d'heure de la semaine je regarde si j'ai un rdv qui commence à ce quart d'heure.
 
Bête et méchant. Probablement pas le plus efficace, mais ça marche, (contrairement à ce qu'on pourrait penser) c'est rapide, ...
Problème, j'ai des besoins de pouvoir créer des rdv de plusieurs jours, genre de vendredi 8 juin 10h à mardi 12 jun 17h... et là tout s'écroule.
 
Voilà, je suis preneur de suggestions sur la manière dont je pourrais procéder parce que je sèche un peu.


Message édité par depart le 10-06-2018 à 15:34:22
mood
Publicité
Posté le 10-06-2018 à 14:09:49  profilanswer
 

n°2316766
MaybeEijOr​Not
but someone at least
Posté le 10-06-2018 à 14:35:35  profilanswer
 

Pas compris les histoires de quarts d'heure, tu peux aussi bien faire ta règle de 3 sur la durée de l'évènement sur 1 un jour.

 

Pour la bdd, il faut stocker ta date complète avec l'heure pour le début et la fin du rdv je pense, puis sélectionner tous les évènements dont :
- la date de début est inférieure à la date de début de semaine ET la date de fin supérieure à la date de début de semaine,
- la date de début est supérieure à la date de début de semaine ET inférieure à la date de fin de semaine.

 

Après pour l'affichage, tu calcules la durée de l'évènement sur chaque jour de la semaine et tu crées une div sur chaque jour de la semaine qui fait :
HauteurDiv = hauteur d'une journée en pixels x durée évènement sur le jour / durée d'une journée
OffsetDiv = hauteur d'une journée en pixels x heure début évènement sur le jour / durée d'une journée
Après faudra que tu gères que les collisions d'évènement, probablement en gérant la largeur de tes divs en fonctions des collisions.


Message édité par MaybeEijOrNot le 10-06-2018 à 14:37:11

---------------
C'est en écrivant n'importe quoi qu'on devient n'importe qui.
n°2316771
depart
Posté le 10-06-2018 à 15:45:04  profilanswer
 

mes histoires de quart d'heure, c'est que comme on agenda est subdivisé en quart d'heures, je boucle de la manière suivante :
sur chaque jour
     sur chaque quart d'heure de la journée
          sur chaque rdv de la semaine pour voir s'il commence ou non à ce quart d'heure précis. Si oui, alors je l'affiche et du coup il est en positionnement relatif à ce quart d'heure (pas besoin d'offset par rapport à un absolu).
 
c'est barbare, mais je n'avais pas vu de ralentissement particulier même sur des milliers de rdv pour une semaine donnée.
 
Maintenant ton idée d'offset par rapport au début de la journée est très intéressant.
D'ailleurs offset par rapport à la journée ou carrément à la semaine (x,y) ?
 
Pour les rdv sur plusieurs jours, notamment ceux sur une même semaine, ça veut aussi dire qu'il faut que je REboucle sur chaque jour et que je prenne en compte :
- les rdv dont la date de début est inférieure au jour courant (dans la boucle) et la date de fin est >= au jour courant
 
petit aperçu de la tronche du calendrier :
https://reho.st/medium/self/94eb5b951b9e6f3cf553c84215ef2df90feca87d.jpg


Message édité par depart le 10-06-2018 à 15:47:17
n°2316772
MaybeEijOr​Not
but someone at least
Posté le 10-06-2018 à 16:45:41  profilanswer
 

Je ne pense pas que ta solution du quart d'heure soit une bonne solution. Je n'y vois pas d'intérêt et au contraire ça complexifie le problème et multiplie des étapes inutiles.

 

Ce qu'il faut faire à mon avis :

 

1- définir une vue (jour, semaine, mois, etc.)
2- effectuer les requêtes en fonction de la vue définie
3- créer la vue

 

Le troisième point va vraiment dépendre de la structure de ton calendrier. Afin de gérer plus facilement les collisions, je pense qu'il faut boucler sur tes évènements récupérés afin de les répartir sur chaque colonne (jour) du calendrier. Tu commences avec un tableau vide de la taille du nombre de colonnes. Tu boucles sur tes évènements, pour chaque évènement tu calcules l'heure de début et de fin sur chaque colonne. Un évènement sur 2 jours par exemple, commencera à 10h et finira à 24h le jour 1 et commencera à 0h et finira à 14h le jour 2. Donc tu remplies ton tableau avec :
$array[colonne1] = [[id évènement, heure début, heure fin, 0]]
$array[colonne2] = [[id évènement, heure début, heure fin, 0]]
$array[colonne3] = [] tu laisses vide car pas la peine de surcharger le tableau
etc.

 

Ensuite sur chaque colonne tu boucles chaque évènement pour déterminer les chevauchements :

Code :
  1. $arrayLength = count($array[colonne1]);
  2. for($i = 0; $i < $arrayLength; $i++) {
  3.   for($j = $i; $j < $arrayLength; $j++) {
  4.      si chevauchement plage évènement $i avec plage évènement $j alors {
  5.         $array[colonne1][$i][3]++;
  6.         $array[colonne1][$j][3]++;
  7.      }
  8.   }
  9. }
 

Il y a surement plus propre qu'une double boucle imbriquée, surtout qu'il faut aussi boucler sur chaque colonne donc ça nous fait 3 boucles imbriquées mais c'est pour t'expliquer l'idée.
Une fois que tu as les heures de début et de fin de chaque évènement pour chaque colonne, ainsi que le nombre de chevauchements, tu peux calculer la hauteur d'offset de l'évènement, sa hauteur et sa largeur et ainsi créer la div qui va bien.
Au passage je parlais de pixels dans mon post précédent, mieux vaut probablement partir sur une colonne conteneur et des divs évènements dedans aux dimensions en pourcentage de ce conteneur.

  

Exemple sur 4 jours de deux évènements :
$array[colonne1] = [[#47, 10h, 24h, 0]]
$array[colonne2] = [[#47, 0h, 12h, 1], [#48, 9h, 24h, 1]]
$array[colonne3] = [[#48, 0h, 16h, 0]]
$array[colonne4] = []

 

Colonne 1 : une div de 100/(0+1) = 100% de large et positionnée à 100*10/24 = 42% du haut de la colonne 1 et faisant 100*(24-10)/24 = 58% de la hauteur de la colonne 1.
Colonne 2 :
   - une div de 100/(1+1) = 50% de large et positionnée à 100*0/24 = 0% du haut de la colonne 2 et faisant 100*(12-0)/24 = 50% de la hauteur de la colonne2.
   - une div de 100/(1+1) = 50% de large et positionnée à 100*9/24 = 38% du haut de la colonne 2 et faisant 100*(24-9)/24 = 63% de la hauteur de la colonne2.
Colonne 3 : une div de 100/(0+1) = 100% de large et positionnée à 100*0/24 = 0% du haut de la colonne 3 et faisant 100*(16-0)/24 = 67% de la hauteur de la colonne 3.
Colonne 4 : rien


Message édité par MaybeEijOrNot le 10-06-2018 à 16:57:14

---------------
C'est en écrivant n'importe quoi qu'on devient n'importe qui.
n°2316852
depart
Posté le 11-06-2018 à 20:39:53  profilanswer
 

Merci beaucoup, je tente de me lancer demain (aujourd'hui j'ai passé ma journée à batailler avec du JS pour faire un joli formulaire de saisie de date-heure de début et de fin, et de les lier pour en cas de modif de la date de début ça décale d'autant la date de fin), je ne pensais pas galérer autant :(
 
/3615 mylife


Message édité par depart le 11-06-2018 à 20:40:13
n°2316886
depart
Posté le 12-06-2018 à 15:11:21  profilanswer
 

Ca marche !!!
 
j'ai donc splitté ma requête sql par jour pour sortir chaque jour tous les rdv dont la date de début est aujourd'hui ou alors dont la date de début est avant aujourd'hui ET la date de fin aujourd'hui ou après.
ensuite tes conseils sont parfaits, j'ai fait :
- un offset par rapport au début de la journée courante, avec des exceptions pour gérer les rdv commencés la veille
- une hauteur au prorata de la durée de la journée à afficher avec là encore des exceptions pour ne pas que ça dépasse (genre agenda qui affiche jusqu'à 20h mais rdv qui va jusqu'au lendemain)
 
Ca a l'air nickel... sauf sur mobile où j'ai des décalages de quelques pixels... à creuser.
 
Pour les collisions ça n'est pas trop prévu dans mon appli pour l'instant mais j'ai pris note de l'idée. Plutôt que de diviser la largeur de la colonne en deux ou plus, j'ai vu que google agenda par exemple fait aussi un petit décalage de quelques pixels + largeur un peu moindre, c'est une autre piste intéressante (en fait ils font en, fonction de la zone de chevauchement, c'est assez intelligent), mais c'est du détail d'affichage...
 
En tout cas gros merci pour m'avoir aiguillé dans la bonne direction.


Message édité par depart le 12-06-2018 à 15:13:14
n°2316890
MaybeEijOr​Not
but someone at least
Posté le 12-06-2018 à 20:29:29  profilanswer
 

Oui tu peux faire un chevauchement des évènements en les décalant légèrement et en faisant passer au premier plan celui qui est survolé par la souris de l'utilisateur.
 
Plein de choses sont envisageables. Par exemple ton idée de quart d'heures n'est probablement pas la meilleure pour l'affichage des RDVs mais reste une bonne idée pour la création des évènements. Tu peux ainsi proposer à l'utilisateur de créer un évènement en cliquant sur la plage de la journée, l'évènement est créé en arrondissant l'heure au quart d'heure précédent. Puis l'utilisateur peut étendre l'évènement par quarts d'heure. Tout en laissant la possibilité d'afficher une autre page pour gérer des options avancées dont l'heure non arrondie.
Puis cela peut vraiment prendre du sens dans un contexte de réservations où tu dois bloquer des plages précises et non à des heures libres.
 
Il peut y avoir énormément de choses à faire pour un agenda. D'ailleurs comme tu le dis, tu as des petits décalages sur mobile, je ne voulais pas trop rentrer dans les détails pour ne pas t'inonder d'informations. Mais une chose intéressante avec la technique que je t'ai décrite, serait de vérifier et faire en sorte qu'une plage à heures (ou quarts d'heure) rondes commence et s'arrête pile au bon niveau. En effet, avec la règle de 3 tu peux te retrouver avec des arrondis formant un petit décalage qui n'a pas lieu d'être.


---------------
C'est en écrivant n'importe quoi qu'on devient n'importe qui.

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  PHP

  Affichage évènement de plusieurs jours sur un calendrier

 

Sujets relatifs
[RESOLU] variable contenant plusieurs valeurs possiblesProblème d'affichage d'un bouton
Indication du slide actif avec un slider Html/CSSProblème d'affichage d'image
[Langage C] Problème d'affichage Chat 2 clientsPetit programme pour scanner plusieurs pages à la suite.
recherche liste mot dans plusieurs fichiers[Ajax] Récupèrer l'action lors d'événement après rechargement de page
[Cognos]Calendrier[Perl] Remplacer plusieurs lignes par le résultat d'un appel externe
Plus de sujets relatifs à : Affichage évènement de plusieurs jours sur un calendrier


Copyright © 1997-2018 Hardware.fr SARL (Signaler un contenu illicite) / Groupe LDLC / Shop HFR