IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

BIRT Discussion :

[birt designer] Graphique, date et JavaScript


Sujet :

BIRT

  1. #1
    Membre averti
    Homme Profil pro
    Inscrit en
    Novembre 2011
    Messages
    36
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2011
    Messages : 36
    Par défaut [birt designer] Graphique, date et JavaScript
    Bonjour,

    J'ai quelque question sur l'utilisation du BIRT designer

    Prenons un dataset simple : date (Date Time), montant (Integer).

    je crée un graphique des montants en fonction de la date.

    Et j'aimerai avoir un paramètre avec lequel je puisse choisir la granularité du graphe (Année, trimestre, mois, semaine, jour...).

    Et en plus j'aimerai que sur le graphe s'affiche les colonnes des dates ou il n'y as pas de valeurs (le fait qu'il n'y ai rien a une telle date est une information), un espace vide autrement dit. (les dates n'ayant pas de montant ne sont pas dans le dataset).

    Donc la solution que j'applique pour l'instant et qui ne me convient pas :
    j'ai un paramètre granularité et j'ai fait une fonction qui en renvoit une chaine de caractère formatée representant la date en fonction de la date et du paramètre.
    ex : si mon paramètre est sur "Trimestre"
    01/01/2008 => "1er trimestre 2008"

    Le problème c'est que si à une date n'est pas dans mon dataset, ça colonne n’apparaîtra dans mon graphe (ce qui est néanmoins normal...)
    Autre problème : la case "optional grouping" dans l’éditeur de graphe devient inutilisable car si on l'utilise on ne peut plus trier l'axe des abscisses par la date, il se triera en fonction de ce que je met dedans, or dedans il y a une chaine de caractère... M'enfin les mois trier par ordre alphabétique sont moyennement intéressant voyez-vous

    J'ai bien pensé a ajouter ces dates manquantes avec un montant nul via ma requête SQL, mais ça me parait un peu lourd.

    J'ai trouvé dans l'éditeur de graphe qu'il pouvait grouper des Date Time par granularié, mais du coup je peut plus utiliser mon paramètre...

    Du coup je me demandais si il y avait des propriétés javascript pour ça mais j'arrive pas à trouver... J'ai mal chercher peut être ?

    Donc pour résumé
    Comment je fais via une fonction javascript (ou pas) pour changer la granularité d'une date sur graphe ?
    Comment je fais pour qu'il affiche les dates qu'il n'y a pas dans mon dataset ?
    Si jamais vous avez une doc qui regroupe toute les propriétés des graphes n'hésitez pas à partager !

    D'autres questions
    Si jamais je trouve que mon graphe est trop large (du coup la légende peut être loin de l'endroit où l'on regarde), est ce que je peut le tronquer : faire deux graphes l'un en dessous de l'autre avec les valeurs qui se suivent. Où alors faire une légende qui suit la vue ?

    Bon j'avais une ou deux autres questions mais je me rappelle plus...

    En tous cas, merci d'avance à tous ceux qui prendront la peine de répondre à mes questions !

  2. #2
    Membre émérite
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Mai 2009
    Messages
    529
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Mai 2009
    Messages : 529
    Par défaut
    Salut,

    Je vois que tu as déjà bien fait le tour de la question

    Avant tout, je pense que le socle indispensable est de disposer d'une dimension "Jours", qui contienne tous les jours de la période à restituer. C'est assez rapidement réalisable avec un dataset scripté: une petite classe java qui reçoit "date début" - "date de fin" en entrée et retourne tous les jours de l'intervalle. Pour ceux qui frémissent à l'évocation du triplet "dataset scripté java", il y a heureusement des solutions plus directes: par exemple créer sous Excel la liste de tous les jours possibles des 20 prochaines années à filtrer dans le dataset, et charger cette liste dans une table du SGBD ou un fichier plat dans le resource path.

    L'idéal est de se créer une source de la forme:

    <date jour>;<code mois>;<libellé mois>;<code trimestre>;<libellé trimestre>; <code année>
    par exemple:
    01/01/2011;201101;Janvier 2011;2011T1;Trimestre 1 2011;2011
    01/02/2011;201101;Janvier 2011;2011T1;Trimestre 1 2011;2011
    ...
    02/02/2011;201102;Février 2011;2011T1;Trimestre 1 2011;2011

    Une fois cette source en main, il y a plusieurs solutions pour résoudre ta fonctionnalité (jointure externe dans la requête d'origine, ou joined datasets externe aprés la requête, ou encore utiliser les API pour sélectionner le bon niveau dans un crosstab), mais à ma connaissance aucune n'est franchement simple. Pour ce genre de chose je pense qu'il faut éviter de charger directement le dataset dans un graphique, cela amène comme tu as pu le constater beaucoup de soucis: c'est à mon avis préférable de découper la complexité en passant par les étapes dataset=>datacube=>crosstab=>chart , ou éventuellement dataset=>table => chart

    Je développe pas plus pour le moment car tu as déjà peut être résolu le cas et ce serait assez long !
    A+

  3. #3
    Membre averti
    Homme Profil pro
    Inscrit en
    Novembre 2011
    Messages
    36
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2011
    Messages : 36
    Par défaut
    L'idée du dataset qui contiendrait toutes les dates comprise dans mon intervalle me satisferai grandement.

    Cela dit, importer ces valeurs depuis un fichier plat ou xml est pour moi inconcevable car ce ne serai pas une solution pérenne.

    Il reste donc la solution du dataset crée dynamiquement avec des scripts.

    Sauf que j'ai beau chercher je trouve rien
    (y compris dans la FAQ)

    Donc si quelqu'un pouvait m'aider
    Je ne sait absolument pas ce qu'il faut mettre dans onfetch.

    Merci d'avance !

  4. #4
    Membre émérite
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Mai 2009
    Messages
    529
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Mai 2009
    Messages : 529
    Par défaut
    Salut, voici la démarche:

    1-créer un datasource de type "scripted datasource"
    2-créer un dataset relié à ce nouveau datasource, créer manuellement le(s) champs en output: faisons simple, un seul champs "day" de type date.
    3-Dans l'évènement "open" du dataset il faut initialiser le tableau qui contient les valeurs du dataset et un compteur. Par exemple en initialisant un tableau en dur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    currentrow=0;
    sourcedata = new Array(5);
    sourcedata [0] = "2011-01-01";
    sourcedata [1] = "2011-01-02";
    sourcedata [2] = "2011-01-03";
    sourcedata [3] = "2011-01-04";
    sourcedata [4] = "2011-01-05";
    4-Dans le Fetch, affecter le champs output avec la valeur correspondante et incrémenter le compteur, quelquechose dans le genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    if ( currentrow < sourcedata.length ){
    	row["day"] = sourcedata[currentrow];
    	currentrow++;
    	return true;
    }
    	return false;
    En pièce jointe l'exemple correspondant rptdesign avec le tableau en dur à 5 valeurs, qu'il faudra évidemment remplacer par une création dynamique de ton intervalle de date. Au final la fonction open ressemblera à quelquechose comme ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    importPackage(Packages.<ma classe java>);
     
    var datemin = params["Datemin"].value;
    var datemax = params["Datemax"].value;
     
    days = new VisioDays();
     
    currentrow=0;
    sourcedata=days.getDaysDimension(datemin, datemax);
    Ici j'utilise un objet java "VisioDays" dont la méthode "getDaysDimension" me renvoie un tableau de type String[] contenant la liste des jours dans l'intervalle, mais tu peux tout aussi bien le faire directement en javascript, sans t'embêter avec du java.

    Une fois que ça fonctionne, il faut créer un "joined dataset" en jointure full externe entre cette dimension jour et la source de ton rapport et la première partie du problème sera résolue Reste le cas des niveaux agrégés mois et trimestre, on verra quand tu en seras là
    Fichiers attachés Fichiers attachés

  5. #5
    Membre averti
    Homme Profil pro
    Inscrit en
    Novembre 2011
    Messages
    36
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2011
    Messages : 36
    Par défaut
    Tout d'abord un grand merci !

    Tu as résolu mon problèmes des dates.
    Il me manquait juste l'info sur les scripted dataset.

    Il ne reste plus que le problème sur les aggregation dans un graphe.

    Aurait tu une idée pour agrégé et formaté dynamiquement les dates (en abscisse) dans un graphe en fonction d'un paramètre sans les changé de type (DateTime) ?

    J'ai fait une fonction qui me renvoi une chaine représentant la date formaté en fonction d'un paramètre, ça marche bien, mais je ne peut plus utiliser une fonctionnalité des graphes dont j'ai besoin.

    Merci d'avance !

  6. #6
    Membre émérite
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Mai 2009
    Messages
    529
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Mai 2009
    Messages : 529
    Par défaut
    Salut,

    et bien félicitations tu as fait le plus dur tu es presque au bout de tes peines. Je vois 2 types de solutions possibles, à toi de choisir la plus appropriée à ton cas.

    Solution 1: champs calculés
    1/créer 2 champs calculés dans le dataset scripté (dimension jour): "codeAggregat":integer et "libelleAggregat":String, avec du javascript sans doute très proche de la fonction que tu as réalisée.
    codeAggregat sera utilisé pour les tris, libelleAggregat pour l'affichage. Donc par exemple si le parametre est le trimestre, codeAggregat contiendra 1, 2, 3 ou 4. et libelleAggregat (Trimestre 1, Trimestre 2,...). Il est possible qu'il faille réouvrir le "joined dataset" pour que ces nouveaux champs soient transportés dans le dataset principal.
    2/ créer un datacube avec la mesure du rapport et une dimension "Temps" basée sur codeAggregat, avec la propriété displayName à "libelleAggregat"
    3/Drag & drop du datacube pour créer un crosstab dans le rapport, puis clique droit sur le crosstab -> create chart view

    L'avantage de cette solution c'est que le datacube te débarrasse du problème de l'aggrégation, et le crosstab te permet de trier sans contraintes.

    Solution 2: Hiérarchie
    Un peu plus brutale mais ça peut être utile.
    1/Toujours dans le dataset scripté, créer par des champs calculés les champs année, trimestre, mois ,semaine, en code et en libellé si besoin. Si les libellés ne sont pas indispensables cette étape est inutile, birt créera automatiquement la hiérarchie dans le datacube à partir de la date.
    2/Créer un datacube avec la mesure et une dimension "Temps" en hiérarchie:Année->Trimeste->Mois->Semaine->jour
    3/Créer un crosstab par niveau, leur donner le nom du niveau, les transformer en "create chart view" comme ci dessus
    4/Dans l'évènement beforeFactory du rapport, supprimer par javascript les crosstab inutiles en fonction du paramètre, quelquechose comme:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    TrimestreCrosstable = reportContext.getReportRunnable().designHandle.getDesignHandle().findElement("Trimestre");
    MoisCrosstable= reportContext.getReportRunnable().designHandle.getDesignHandle().findElement("Mois");
     
    if (params["NiveauAggregat"].value == "Mois"){
    TrimestreCrosstable.drop();
    }
    else{
    MoisCrosstable.drop();
    }
    Evidemment la solution 2 serait plus élégante en sélectionnant le bon niveau hiérarchique par API javascript, mais je te déconseille de te lancer dans cette voie sans un exemple concret sous les yeux. Bon courage A+

  7. #7
    Membre averti
    Homme Profil pro
    Inscrit en
    Novembre 2011
    Messages
    36
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2011
    Messages : 36
    Par défaut
    Wouhou ça marche !

    enfin sur un rapport test, il reste plus qu'à mettre ça en pratique !

    Du coup, j'ai fait la solution 1.

    A noter que pour codeAgregat, prenons l'exemple du trimestre, si nos dates s'étendent sur plusieurs années, il ne faut pas se contenter de mettre uniquement le numéro du trimestre car sinon l’agrégation se fera sans prendre en compte l'année (par exemple Trimestre 1 comprendra le T1 de 2010 et de 2011)
    Bon par contre c'est pas compliqué a éviter.

    En faite je ne savais pas du tout utiliser les datacubes, ce qui m'amène à une question importante : Comment tu as appris tout ça ? Y a une doc à un endroit ?

    En tout cas, merci beaucoup !

  8. #8
    Membre émérite
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Mai 2009
    Messages
    529
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Mai 2009
    Messages : 529
    Par défaut
    Oui exact je n'avais pas pensé au cas de plusieurs années well done!
    Perso j'ai appris ce genre de choses en écumant les forums, en particulier grâce aux réponses toujours avisées de Jason Weathersby, Michael Williams, Bim, Stefan etc et par des tests les longues soirées d'hiver au coin du feu
    A+

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [BIRT Designer 2.2.2] Problème Label et Graphique
    Par zakariaz dans le forum BIRT
    Réponses: 2
    Dernier message: 18/07/2014, 13h56
  2. [Birt designer] Inclure un fichier JavaScript
    Par NiarK-74 dans le forum BIRT
    Réponses: 17
    Dernier message: 29/11/2011, 09h26
  3. format date validator javascript?
    Par cyrano_de_bergerac dans le forum ASP.NET
    Réponses: 10
    Dernier message: 31/12/2007, 13h42
  4. validation fomat date en javascript
    Par badoress dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 03/10/2007, 11h35
  5. Date et javascript
    Par Jéjé81 dans le forum Général JavaScript
    Réponses: 7
    Dernier message: 09/11/2004, 23h57

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo