Précédent   Forum des professionnels en informatique > Logiciels > Solutions d'entreprise > Business Intelligence > BIRT
BIRT Forum d'entraide sur BIRT (Business Intelligence and Reporting Tools). Avant de poster --> FAQ BIRT,Tutoriels BIRT
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 13/11/2011, 18h01   #1
Invité régulier
 
Homme
Inscription : novembre 2011
Messages : 36
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations forums :
Inscription : novembre 2011
Messages : 36
Points : 8
Points : 8
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 !
NiarK-74 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/11/2011, 16h54   #2
Membre confirmé
 
Homme
Consultant en Business Intelligence
Inscription : mai 2009
Messages : 186
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Consultant en Business Intelligence

Informations forums :
Inscription : mai 2009
Messages : 186
Points : 289
Points : 289
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+
donino est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/11/2011, 17h39   #3
Invité régulier
 
Homme
Inscription : novembre 2011
Messages : 36
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations forums :
Inscription : novembre 2011
Messages : 36
Points : 8
Points : 8
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 !
NiarK-74 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/11/2011, 09h20   #4
Membre confirmé
 
Homme
Consultant en Business Intelligence
Inscription : mai 2009
Messages : 186
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Consultant en Business Intelligence

Informations forums :
Inscription : mai 2009
Messages : 186
Points : 289
Points : 289
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 :
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 :
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 :
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
Type de fichier : zip DimensionJour.zip (1,6 Ko, 1 affichages)
donino est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 17/11/2011, 13h10   #5
Invité régulier
 
Homme
Inscription : novembre 2011
Messages : 36
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations forums :
Inscription : novembre 2011
Messages : 36
Points : 8
Points : 8
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 !
NiarK-74 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/11/2011, 14h39   #6
Membre confirmé
 
Homme
Consultant en Business Intelligence
Inscription : mai 2009
Messages : 186
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Consultant en Business Intelligence

Informations forums :
Inscription : mai 2009
Messages : 186
Points : 289
Points : 289
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 :
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+
donino est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 17/11/2011, 21h32   #7
Invité régulier
 
Homme
Inscription : novembre 2011
Messages : 36
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations forums :
Inscription : novembre 2011
Messages : 36
Points : 8
Points : 8
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 !
NiarK-74 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/11/2011, 09h09   #8
Membre confirmé
 
Homme
Consultant en Business Intelligence
Inscription : mai 2009
Messages : 186
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Consultant en Business Intelligence

Informations forums :
Inscription : mai 2009
Messages : 186
Points : 289
Points : 289
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+
donino est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 07h05.


 
 
 
 
Partenaires

Hébergement Web