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 :

[2.5.1][Graphique] Ajouter des marges dynamiques à l'axe vertical d'un graphique


Sujet :

BIRT

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre expérimenté

    Inscrit en
    Avril 2010
    Messages
    178
    Détails du profil
    Informations forums :
    Inscription : Avril 2010
    Messages : 178
    Par défaut [2.5.1][Graphique] Ajouter des marges dynamiques à l'axe vertical d'un graphique
    Bonjour,

    J'ai un besoin de mise en forme graphique qui requiert apparemment des compétences Javascript qui me manquent.

    Le problème est assez simple : sur un graphique de type "lignes", arriver à redéfinir les extrêmes de l'échelle verticale de manière à rajouter des marges au dessus et en dessous.

    Par exemple, si une série de données évolue entre 50 et 100, au lieu d'avoir les extrêmes de mon axe à 50 et 100, j'aimerais qu'ils soient à min : 50 - (100-50)*10% = 45 ; max : 100 + (100-50)*10% = 105.

    En gros, comme l'auto-scale mais avec un pourcentage en plus.

    Je n'ai pas l'impression que ce soit faisable avec les options du designer (dans l'éditeur de graphiques, onglet "format chart", sous-menu "Chart Area/Axis/Y-Axis", bouton "Scale", on peut définir des valeurs absolues, et surtout, constantes, rien de dynamique). J'ai essayé de voir en javascript, mais je ne le maîtrise pas assez pour comprendre la documentation dont je dispose.

    J'ai essayé d'utiliser la FAQ officielle et la Chart Engine API Reference (voir org.eclipse.birt.chart.model.impl.ChartWithAxesImpl) mais je n'arrive pas à manipuler le modèle. Je pense que c'est faisable en javascript mais j'ai besoin d'aide pour pondre du code correct (notamment pour : accéder aux données qui alimentent le graphique, et déduire les valeurs extrêmes du jeu de données).

    Merci d'avance pour votre aide.

  2. #2
    BiM
    BiM est déconnecté
    Expert confirmé
    Avatar de BiM
    Femme Profil pro
    Consultante/Formatrice BIRT & Ingénieur Java/J2EE/GWT
    Inscrit en
    Janvier 2005
    Messages
    7 796
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 39
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultante/Formatrice BIRT & Ingénieur Java/J2EE/GWT

    Informations forums :
    Inscription : Janvier 2005
    Messages : 7 796
    Par défaut
    Bonjour,

    Il te suffit d'ajouter un script à ton graphique :
    Code JavaScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function beforeGeneration(chart, icsc) {
    	importPackage(Packages.org.eclipse.birt.chart.model.data.impl);
     
    	/* Récupération de l'axe des ordonnées */
    	yAxis = chart.getAxes().get(0).getAssociatedAxes().get(0);
     
    	/* Initialisation des valeurs minimale et maximale de l'ordonnée */
    	yAxis.getScale().setMin(NumberDataElementImpl.create(MaValeurMinimale));
    	yAxis.getScale().setMax(NumberDataElementImpl.create(MaValeurMaximale));
    }

  3. #3
    Membre expérimenté

    Inscrit en
    Avril 2010
    Messages
    178
    Détails du profil
    Informations forums :
    Inscription : Avril 2010
    Messages : 178
    Par défaut
    Merci pour la réponse

    J'avais réussi à trouver un exemple de cette fonction, mais ce qu'il me manque, c'est le code permettant de définir "MaValeurMinimale" et "MaValeurMaximale".
    Il faut accéder aux valeurs du jeu de données correspondant.

    Au final, je pense que j'ai simplement besoin de trouver la syntaxe d'accès à un jeu de données en javascript. Sachant qu'il s'agit du jeu de données lié à mon graphique, c'est sûrement super simple, mais je galère à trouver de la doc ou un exemple de syntaxe.

    Sachant que je n'aurais aucun problème à extraire les valeurs min et max de mon jeu de données en lui ajoutant les agrégations qui vont bien, pourrais-tu s'il te plait m'indiquer la syntaxe de manipulation du jeu de données en javascript (ou me donner un lien vers une page l'expliquant) ?

    Merci encore

  4. #4
    BiM
    BiM est déconnecté
    Expert confirmé
    Avatar de BiM
    Femme Profil pro
    Consultante/Formatrice BIRT & Ingénieur Java/J2EE/GWT
    Inscrit en
    Janvier 2005
    Messages
    7 796
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 39
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultante/Formatrice BIRT & Ingénieur Java/J2EE/GWT

    Informations forums :
    Inscription : Janvier 2005
    Messages : 7 796
    Par défaut
    Je me pose la même question

    Bon je vais regarder ce que je trouve. Pour l'instant, j'ai compris que le beforeGeneration se faisait après le afterDataSetFilled, ce qui est plutôt une bonne nouvelle !! Cela veut dire que les données ont été récupérées avant la fonction dont on a besoin.

  5. #5
    BiM
    BiM est déconnecté
    Expert confirmé
    Avatar de BiM
    Femme Profil pro
    Consultante/Formatrice BIRT & Ingénieur Java/J2EE/GWT
    Inscrit en
    Janvier 2005
    Messages
    7 796
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 39
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultante/Formatrice BIRT & Ingénieur Java/J2EE/GWT

    Informations forums :
    Inscription : Janvier 2005
    Messages : 7 796
    Par défaut
    Voilà ce que j'ai réussi à faire :
    Code JavaScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    function afterDataSetFilled( series, dataSet, icsc ) {
    	/* Récupération des valeurs des séries uniquement */
    	if (series.getSeriesIdentifier() != null && !series.getSeriesIdentifier().toString().isEmpty()) {
    		valeurs = dataSet.getValues()
     
    		/* Recherche du minimum et du maximum */
    		min = Number.MAX_VALUE;
    		max = Number.MIN_VALUE;
    		for (i = 0; i < valeurs.length; i++) {
    			valeur = valeurs[i];
    			if (valeur < min) {
    				min = valeur;
    			}
    			if (valeur > max) {
    				max = valeur;
    			}
    		}
     
    		/* Ajout et substraction de 10% de l'écart aux bornes */
    		ecart = (max - min)/10;
    		min = BirtMath.subtract(min, ecart);
    		max = BirtMath.add(max, ecart);
     
    		/* Enregistrement des valeurs minimale et maximale dans des paramètres */
    		icsc.getExternalContext().getScriptable().setParameterValue("MinValue", min);
    		icsc.getExternalContext().getScriptable().setParameterValue("MaxValue", max);
    	}
    }
     
    function beforeGeneration(chart, icsc) {
    	importPackage(Packages.org.eclipse.birt.chart.model.data.impl);
     
    	/* Récupération des valeurs minimale et maximale */
    	min = icsc.getExternalContext().getScriptable().getParameterValue("MinValue");
    	max = icsc.getExternalContext().getScriptable().getParameterValue("MaxValue");
     
    	/* Récupération de l'axe des ordonnées */
    	yAxis = chart.getAxes().get(0).getAssociatedAxes().get(0);
     
    	/* Initialisation des valeurs minimale et maximale de l'ordonnée */
    	yAxis.getScale().setMin(NumberDataElementImpl.create(min));
    	yAxis.getScale().setMax(NumberDataElementImpl.create(max));
    }

    Il faut noter que les données dans les graphiques ne sont pas du tout utilisées de la même façon que dans des tableaux, c'est très spécifique.

    Si tes bornes donnent des nombres à virgule alors que tu n'as que des entier, tu dois définir ton type de données dont tu extrais la valeur en Decimal et non Integer. Cela se change dans l'onglet Select Data de l'édition de graphique, bouton DataBinding.

  6. #6
    Membre expérimenté

    Inscrit en
    Avril 2010
    Messages
    178
    Détails du profil
    Informations forums :
    Inscription : Avril 2010
    Messages : 178
    Par défaut
    Bonjour,

    Tu peux me rajouter à la très longue liste des personnes qui te doivent une fière chandelle. J'applaudis à deux mains et je rends les conclusions :

    J'avais un besoin supplémentaire non exprimé, qui est que mon graphique contient plusieurs courbes et donc autant de jeux de données associés, et toutes doivent être prises en compte pour définir l'échelle de l'axe. Le code actuel ne prend en compte que le dernier axe (la valeur des paramètres étant écrasée à chaque itération de la fonction afterDataSetFilled(), qui est appelée pour chaque jeu de données).

    J'ai pu me rendre compte de ce comportement après test. J'ai d'abord essayé d'utiliser l'objet "series", pour en extraire les jeux de données, faire une boucle dessus et tous les prendre en compte. Voici le code correspondant (qui ne marche pas) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    function afterDataSetFilled( series, dataSet, icsc ) {
    	/* Récupération des valeurs des séries uniquement */
    	if (series.getSeriesIdentifier() != null && !series.getSeriesIdentifier().toString().isEmpty()) {
    		dataSets = series.getDataSets();
     
    		/* Recherche du minimum et du maximum */
    		min = Number.MAX_VALUE;
    		max = Number.MIN_VALUE;
    		for (i = 0; i < dataSets.length; i++) {
    			myDataSet = dataSets[i];
    			valeurs = myDataSet.getValues();
     
    			for (j = 0; j < valeurs.length; j++) {
    				valeur = valeurs[j];
    				if (valeur < min) {
    					min = valeur;
    				}
    				if (valeur > max) {
    					max = valeur;
    				}
    			}
    		}
     
     
    		/* Ajout et substraction de 10% de l'écart aux bornes */
    		ecart = (max - min)/10;
    		min = BirtMath.subtract(min, ecart);
    		max = BirtMath.add(max, ecart);
     
    		/* Enregistrement des valeurs minimale et maximale dans des paramètres */
    		icsc.getExternalContext().getScriptable().setParameterValue("MinValue", min);
    		icsc.getExternalContext().getScriptable().setParameterValue("MaxValue", max);
    	}
    }
     
    function beforeGeneration(chart, icsc) {
    	importPackage(Packages.org.eclipse.birt.chart.model.data.impl);
     
    	/* Récupération des valeurs minimale et maximale */
    	min = icsc.getExternalContext().getScriptable().getParameterValue("MinValue");
    	max = icsc.getExternalContext().getScriptable().getParameterValue("MaxValue");
     
    	/* Récupération de l'axe des ordonnées */
    	yAxis = chart.getAxes().get(0).getAssociatedAxes().get(0);
     
    	/* Initialisation des valeurs minimale et maximale de l'ordonnée */
    	yAxis.getScale().setMin(NumberDataElementImpl.create(min));
    	yAxis.getScale().setMax(NumberDataElementImpl.create(max));
    }
    J'ai eu des erreurs relatives au contenu des données, j'ai du aller prendre des données invalides ou je ne sais quoi. Mais je n'ai pas creusé plus car, vu la signature de la fonction (afterDataSetFilled( series, dataSet, icsc )), je me suis dit qu'elle devait être appelée pour chaque jeu de données, j'ai donc modifié le code pour conserver les appels successifs de la fonction, et ça a marché.
    Voici le code final, avec deux trois modifications (déplacement de la prise en compte de l'écart dans les valeurs min et max, ajout d'un arrondi pour avoir une echelle pas trop moche) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    function afterDataSetFilled( series, dataSet, icsc ) {
    	/* Récupération des valeurs des séries uniquement */
    	if (series.getSeriesIdentifier() != null && !series.getSeriesIdentifier().toString().isEmpty()) {
    		valeurs = dataSet.getValues()
     
    		/* Recherche du minimum et du maximum */
    		min = icsc.getExternalContext().getScriptable().getParameterValue("MinValue");
    		max = icsc.getExternalContext().getScriptable().getParameterValue("MaxValue");
    		if(min == null) min = Number.MAX_VALUE;
    		if(max == null) max = Number.MIN_VALUE;
    		for (i = 0; i < valeurs.length; i++) {
    			valeur = valeurs[i];
    			if (valeur < min) {
    				min = valeur;
    			}
    			if (valeur > max) {
    				max = valeur;
    			}
    		}
     
    		/* Enregistrement des valeurs minimale et maximale dans des paramètres */
    		icsc.getExternalContext().getScriptable().setParameterValue("MinValue", min);
    		icsc.getExternalContext().getScriptable().setParameterValue("MaxValue", max);
    	}
    }
     
    function beforeGeneration(chart, icsc) {
    	importPackage(Packages.org.eclipse.birt.chart.model.data.impl);
     
    	/* Récupération des valeurs minimale et maximale */
    	min = icsc.getExternalContext().getScriptable().getParameterValue("MinValue");
    	max = icsc.getExternalContext().getScriptable().getParameterValue("MaxValue");
     
    	/* Ajout et substraction de 10% de l'écart aux bornes */
    	ecart = (max - min)*0.1;
    	min = BirtMath.subtract(min, ecart);
    	max = BirtMath.add(max, ecart);
     
    	/* Arrondi externe à la dizaine */
    	min = BirtMath.roundDown(min,-1);
    	max = BirtMath.roundUp(max,-1);
     
    	/* Récupération de l'axe des ordonnées */
    	yAxis = chart.getAxes().get(0).getAssociatedAxes().get(0);
     
    	/* Initialisation des valeurs minimale et maximale de l'ordonnée */
    	yAxis.getScale().setMin(NumberDataElementImpl.create(min));
    	yAxis.getScale().setMax(NumberDataElementImpl.create(max));
    }
    Donc voilà, un grand merci à toi, BiM.

    Question subsidiaire : y a-t-il quelque part de la doc ou un tutoriel expliquant le comportement des méthodes javascript implémentées (pour les graphes, par exemple, pour tout Birt en général) ? Par exemple, pour expliquer le fait que la méthode afterDataSetFilled() soit appelée pour chaque jeu de données. Bref, un schéma comportemental des objets Birt.

    Merci encore et bonne journée

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

Discussions similaires

  1. Ajouter des éléments dynamiquement a un TMenu
    Par toure32 dans le forum Composants VCL
    Réponses: 3
    Dernier message: 20/06/2008, 10h28
  2. Réponses: 3
    Dernier message: 23/04/2007, 13h14
  3. Réponses: 1
    Dernier message: 19/08/2006, 19h40
  4. Réponses: 1
    Dernier message: 14/08/2006, 09h41
  5. Réponses: 6
    Dernier message: 04/01/2006, 11h52

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