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

JavaFX Discussion :

[JavaFX 8] XYChart, extraValue et affichage d'un Node personnalisé


Sujet :

JavaFX

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2014
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2014
    Messages : 11
    Par défaut Custom XYChart : problème affichage d'un Node personnalisé
    Bonjour,

    Je suis plutôt novice en java et encore plus avec javafx, donc la solution est sans doute toute bête mais elle m'échappe.

    En suivant les modèles disponibles dans la documentation Oracle et sur le net, j'ai construit un un chart personnalisé appelé "HisTChart".
    Ce HisTChart fonctionne avec un DateAxis en xAxis et un CategoryAxis en yAxis.

    Les datas traités contiennent une date de début, une catégorie, une date de fin et un titre. La date de fin et le titre sont contenus dans une extraValue personnalisée.

    Ces datas sont affichés sur le HisTChart par un Node personnalisé appelé "TimeRegion" qui se présente comme une Region "tRegion" (couvrant la zone entre la date de début et la date de fin en abscisse, un pourcentage de l'espacement entre catégories en ordonnée) et un Text "tText" pour afficher un texte au dessus.

    J'ai implémenté toutes les méthodes abstraites nécessaires pour faire un chart héritant de XYChart.

    Le TimeRegion s'affiche correctement mais le tRegion qu'il contient ne s'affiche pas. Le tText, lui, s'affiche correctement.

    Si vous pouviez m'aider à saisir où est l'erreur avec la Region contenue dans mon Node, ça soulagerait mon cuir chevelu. Merci d'avance !

    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
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    package histime;
     
    import java.util.Date;
    import java.util.Iterator;
    import javafx.animation.FadeTransition;
    import javafx.event.ActionEvent;
    import javafx.event.EventHandler;
    import javafx.scene.Group;
    import javafx.scene.Node;
    import javafx.scene.chart.Axis;
    import javafx.scene.chart.CategoryAxis;
    import javafx.scene.chart.XYChart;
    import javafx.scene.layout.Region;
    import javafx.scene.text.Text;
    import javafx.util.Duration;
     
    /**
     *
     * @author benoi_000
     */
    public class HisTChart extends XYChart <Date, String> {
     
        public HisTChart(Axis<Date> xAxis, Axis<String> yAxis) {
            super(xAxis, yAxis);
     
        }
     
        @Override
        protected void dataItemAdded(Series<Date, String> series, int itemIndex, Data<Date, String> item) {
           Node timeRegion = createTimeRegion(getData().indexOf(series), item, itemIndex);
            if (shouldAnimate()) {
                timeRegion.setOpacity(0);
                getPlotChildren().add(timeRegion);
                // Effet de transition en fade in
                FadeTransition ft = new FadeTransition(Duration.millis(500), timeRegion);
                ft.setToValue(1);
                ft.play();
            } else {
                getPlotChildren().add(timeRegion);
            }
            //always draw average line on top
            //if (series.getNode() != null) series.getNode().toFront();
        }
     
        @Override
        protected void dataItemRemoved(Data<Date, String> item, Series<Date, String> series) {
            final Node timeRegion = item.getNode();
            if (shouldAnimate()) {
                // suppression en fade out
                FadeTransition ft = new FadeTransition(Duration.millis(500), timeRegion);
                ft.setToValue(0);
                ft.setOnFinished(new EventHandler<ActionEvent>() {
                    @Override public void handle(ActionEvent actionEvent) {
                        getPlotChildren().remove(timeRegion);
                    }
                });
                ft.play();
            } else {
                // suppression barbare !
                getPlotChildren().remove(timeRegion);
            }
        }
     
        @Override
        protected void dataItemChanged(Data<Date, String> data) {
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
        }
     
        @Override
        protected void seriesAdded(Series<Date, String> series, int seriesIndex) {
            for (int j=0; j<series.getData().size(); j++) {
                Data item = series.getData().get(j);
                Node timeRegion = createTimeRegion(seriesIndex, item, j);
                if (shouldAnimate()) {
                    timeRegion.setOpacity(0);
                    getPlotChildren().add(timeRegion);
                    //effet animé fade in du nouveau timeRegion
                    FadeTransition ft = new FadeTransition(Duration.millis(500),timeRegion);
                    ft.setToValue(1);
                    ft.play();
                } else {
                    getPlotChildren().add(timeRegion);
                }
            }
        }
     
        @Override
        protected void seriesRemoved(Series<Date, String> series) {
            for (XYChart.Data<Date, String> d : series.getData()) {
                final Node timeRegion = d.getNode();
                if (shouldAnimate()) {
                    // fade out encore
                    FadeTransition ft = new FadeTransition(Duration.millis(500),timeRegion);
                    ft.setToValue(0);
                    ft.setOnFinished(new EventHandler<ActionEvent>() {
                        @Override public void handle(ActionEvent actionEvent) {
                            getPlotChildren().remove(timeRegion);
                        }
                    });
                    ft.play();
                } else {
                    getPlotChildren().remove(timeRegion);
                }
            }
        }
     
        @Override
        protected void layoutPlotChildren() {
            // si pas de data, pas de layout
            if(getData() == null) return;
     
            // sinon, update des timeRegions
            for (int seriesIndex=0; seriesIndex < getData().size(); seriesIndex++) {
                Series<Date,String> series = getData().get(seriesIndex);
                Iterator<Data<Date,String>> iter = getDisplayedDataIterator(series);
     
                while(iter.hasNext()) {
                    // récupération de l'item
                    Data<Date, String> item = iter.next();
     
                    // récupération de ses valeurs x, y et extravalue
                    double x = getXAxis().getDisplayPosition(getCurrentDisplayedXValue(item));
                    System.out.println("display Position x = " + x);
                    double y = getYAxis().getDisplayPosition(getCurrentDisplayedYValue(item));
                    System.out.println("display position y = " + y);
                    TimeRegionExtraValues extra = (TimeRegionExtraValues)item.getExtraValue();
     
                    //récupération de son Node associé
                    Node itemNode = item.getNode();
     
                    //si l'item a déjà un Node de type TimeRegion, on met à jour ce TimeRegion
                    if (itemNode instanceof TimeRegion && extra != null) {
                        TimeRegion timeRegion = (TimeRegion) itemNode;
     
                        double dateEnd = getXAxis().getDisplayPosition(extra.getDateEnd());
                        System.out.println("display position dateEnd = " + dateEnd);
     
                        // détermination de la hauteur d'un timeRegion
                        CategoryAxis yAxis = (CategoryAxis)getYAxis();
                        double timeRegionHeight = yAxis.getCategorySpacing() * 0.90; // 90% de l'écart entre catégories
                        System.out.println("timeRegionHeight = " + timeRegionHeight);
     
                        // màj de la timeRegion
                        timeRegion.update((dateEnd-x), timeRegionHeight);
     
                        // positionnement de la timeRegion
                        timeRegion.setLayoutX(x);
                        timeRegion.setLayoutY(y-(timeRegionHeight/2));
     
                    }
     
                }
            }
        }
     
        /**
         * Créer un nouveau Node TimeRegion pour un item
         *
         * @param seriesIndex index de la série dans laquelle se trouve l'item
         * @param item        item pour lequel créer la TimeRegion
         * @param itemIndex   index de l'item dans la série
         * @return Nouveau Node pour représenter l'item
         */
        private Node createTimeRegion(int seriesIndex, final Data item, int itemIndex) {
     
            Node timeRegion = item.getNode();
     
            // Vérifier si timeRegion n'est pas déjà créée
            if (timeRegion instanceof TimeRegion) {
     
                ((TimeRegion) timeRegion).setSeriesAndDataStyleClasses("series" + seriesIndex, "data" + itemIndex);
     
            } else {
     
                timeRegion = new TimeRegion("series" + seriesIndex, "data" + itemIndex);
                item.setNode(timeRegion);
     
            }
            return timeRegion;
        }
     
        private static class TimeRegion extends Group {
            private String seriesStyleClass;
            private String dataStyleClass;
            private Region tRegion = new Region();
            private Text tText = new Text();
     
            public TimeRegion(String seriesStyleClass, String dataStyleClass) {
                setAutoSizeChildren(false);
                getChildren().addAll(tRegion, tText);
                this.seriesStyleClass = seriesStyleClass;
                this.dataStyleClass = dataStyleClass;
                updateStyleClasses();
                        }
     
            public void update(double tRegionWidth, double tRegionHeight) {
     
                updateStyleClasses();
                tRegion.resizeRelocate(tRegionWidth/2, tRegionHeight/2, tRegionWidth, tRegionHeight);
                tText.setText("Test !!!");
     
            }
     
            public void setSeriesAndDataStyleClasses(String seriesStyleClass , String dataStyleClass) {
                this.seriesStyleClass = seriesStyleClass;
                this.dataStyleClass = dataStyleClass;
                updateStyleClasses();
            }
     
            private void updateStyleClasses() {
                getStyleClass().setAll("TimeRegion-timeRegion",seriesStyleClass,dataStyleClass);
                tText.getStyleClass().setAll("TimeRegion-tText",seriesStyleClass,dataStyleClass);
                tRegion.getStyleClass().setAll("IimeRegion-tRegion",seriesStyleClass,dataStyleClass);
            }
     
        }
     
        public static class TimeRegionExtraValues {
            private Date dateEnd;
            private String title;
     
            public TimeRegionExtraValues(Date dateEnd, String title) {
                this.dateEnd = dateEnd;
                this.title = title;
            }
     
            public Date getDateEnd() {
                return dateEnd;
            }
     
            public String getTitle() {
                return title;
            }
        }
     
    }

  2. #2
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 900
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 900
    Billets dans le blog
    54
    Par défaut
    Est-ce que tu pourrais nous fournir un exemple de test STP, car la j'en suis reduit a supposer comment peupler le graphe et je ne sais pas trop quoi mettre dedans pour tester :

    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
    public class Test_HisTChart extends Application {
     
        public static void main(String[] args) {
            launch(args);
        }
     
        @Override
        public void start(final Stage primaryStage) {
            final Axis<Date> dateAxis = [...]
            final CategoryAxis categoryAxis =  [...]               
            final HisTChart chart = new HisTChart(categoryAxis, dateAxis);
            [...]
            final StackPane root = new StackPane(chart);
            final Scene scene = new Scene(root);
            primaryStage.setScene(scene);
            primaryStage.setTitle("Test_HisTChart");
            primaryStage.show();
        }
    }
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  3. #3
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2014
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2014
    Messages : 11
    Par défaut [JavaFX 8] XYChart, extraValue et affichage d'un Node personnalisé
    Bonjour à tous,

    J'ai un petit soucis dont je n'arrive pas à cerner l'origine et mes nerfs commencent à être entamés :p

    Voilà mon projet en quelques mots :
    J'essaie développer une petite application pouvant afficher des données datées sous la forme d'une frise chronologique.

    Après maintes recherches, j'ai opté pour l'utilisation d'un XYChart personnalisé.
    Ce XYChart, que j'ai appelé "HisTChart", utilise un DateAxis en abscisse et un CategoryAxis en ordonnée.
    Le DateAxis, je l'ai construit à partir des propositions de Christian Schudt, Pixel Duke et d'autres bloggers (voir ici et http://pixelduke.wordpress.com/2013/...rchart-update/)

    Jusque là, tout va bien. Mon DateAxis fonctionne, mon HisTchart aussi.

    Mon petit problème vient (je crois) de l'implémentation des méthodes abstraites héritées de XYChart, notamment la fameuse layoutPlotChildren().
    Ou peut-être est-ce dans la création des Nodes associés aux données...

    Je m'explique :

    • HisTChart utilise donc un DateAxis (abscisse) et un CategoryAxis (ordonnée).
    • Les données utilisent des ExtraValues et sont donc construites comme suit : (DateDeDébut, StringDeCategorie, ExtraValues(DateDeFin, StringTitre))
    • HisTChart doit afficher ces données comme des Nodes qui affichent une Region étendue entre DateDeDébut et DateDeFin (en abscisse) et alignée sur la catégorie correspondant à StringDeCategorie (en ordonnée).
    • Un Node personnalisé est donc créé : "TimeRegion" (extends Group).
    • Ce TimeRegion contient lui-même une Region "tRegion" et un Text "tText". tRegion est le rectangle étendu entre DateDeDébut et DateDeFin, tText est un Text affichant le StringTitre.



    Les données ont l'air d'être correctement traitées par layoutPlotChildren() et par TimeRegion.update() puisque le tText "Test !!!" ajouté dans TimeRegion.update() (ligne 202 de HisTChart.java) est correctement affiché (au bon endroit et avec le bon layout défini dans le css).

    Par contre, la Region tRegion n'apparait pas... et c'est là que je m'arrache les cheveux
    Les println situés dans layoutPlotChildren() m'indiquent que toutes les valeurs calculées se portent bien...

    Voici le code ou doit se situer l'erreur.

    La classe d'application HisTime.java :

    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
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
     
    package histime;
     
    import java.io.File;
    import java.util.Arrays;
    import java.util.Date;
    import java.util.GregorianCalendar;
    import javafx.application.Application;
    import javafx.collections.FXCollections;
    import javafx.geometry.Rectangle2D;
    import javafx.scene.Group;
    import javafx.scene.Scene;
    import javafx.scene.chart.CategoryAxis;
    import javafx.scene.chart.XYChart;
    import javafx.scene.image.Image;
    import javafx.scene.image.ImageView;
    import javafx.stage.Screen;
    import javafx.stage.Stage;
    import javafx.stage.StageStyle;
     
    public class HisTime extends Application {
     
        @Override
        public void start(Stage primaryStage) {
     
            Group rootGroup = new Group();
            primaryStage.initStyle(StageStyle.UNDECORATED);
     
            Date initDate = new Date();
            Date centralDate = new Date();
            int zoomFactor;
            String [] categories = {"A", "B", "C"};
     
            // DETERMINATION DE LA TAILLE DE LA STAGE EN PLEIN ECRAN
            Rectangle2D primaryScreenBounds = Screen.getPrimary().getVisualBounds();
            primaryStage.setX(primaryScreenBounds.getMinX());
            primaryStage.setY(primaryScreenBounds.getMinY());
            primaryStage.setWidth(primaryScreenBounds.getWidth());
            primaryStage.setHeight(primaryScreenBounds.getHeight());
            Scene scene = new Scene(rootGroup, primaryScreenBounds.getWidth(), primaryScreenBounds.getHeight());
     
            // AJOUT DU CHART PERSONNALISE
     
            DateAxis xAxis = new DateAxis(new GregorianCalendar(1912,5,13).getTime(), new GregorianCalendar(2016,8,19).getTime()); // Dates aléatoires dans le constructeur
            CategoryAxis yAxis = new CategoryAxis();
     
            HisTChart hisTChart = new HisTChart(xAxis, yAxis);
     
            hisTChart.setMinSize(primaryScreenBounds.getWidth()-40, 935);
            hisTChart.setAlternativeColumnFillVisible(false);
            hisTChart.setAlternativeRowFillVisible(true);
     
            hisTChart.getStylesheets().addAll(getClass().getResource("css/histchart.css").toExternalForm());
     
            hisTChart.setLayoutX(10);
            hisTChart.setLayoutY(20);
            hisTChart.setLegendVisible(false);
     
            xAxis.setZoomFactor(35);
            xAxis.setRangeOnCenteredDate(initDate, false); // Méthode perso pour recalculer les valeurs min et max de la DateAxis en fonction d'une date centrale et d'un facteur de zoom.
            yAxis.setCategories(FXCollections.<String>observableArrayList(Arrays.asList(categories)));
            yAxis.setTickLabelsVisible(true);
            yAxis.setAutoRanging(false);
     
            // CHARGEMENT DES DONNEES DANS LE CHART
     
            XYChart.Series series1 =new XYChart.Series<>();
            XYChart.Series series2 =new XYChart.Series<>();
     
            // Les données sont composées comme suit : (DateDeDebut, StringDeCategorie, ExtraValues(DateDeFin, StringTitre))
            series1.setData(FXCollections.observableArrayList(new XYChart.Data(new GregorianCalendar(1986,6,18).getTime(), categories[0], new HisTChart.TimeRegionExtraValues(initDate, "Test"))));
            series2.setData(FXCollections.observableArrayList(new XYChart.Data(new GregorianCalendar(1992,0,11).getTime(), categories[1], new HisTChart.TimeRegionExtraValues(initDate, "Test2"))));
     
            hisTChart.setData(FXCollections.observableArrayList(series1));
            hisTChart.getData().add(series2);
     
            rootGroup.getChildren().add(hisTChart);
     
     
            primaryStage.setScene(scene);
            primaryStage.show();
        }
     
        /**
         * The main() method is ignored in correctly deployed JavaFX application.
         * main() serves only as fallback in case the application can not be
         * launched through deployment artifacts, e.g., in IDEs with limited FX
         * support. NetBeans ignores main().
         *
         * @param args the command line arguments
         */
        public static void main(String[] args) {
            launch(args);
        }
     
    }
    Et voici HisTChart.java :

    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
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
     
    package histime;
     
    import java.util.Date;
    import java.util.Iterator;
    import javafx.animation.FadeTransition;
    import javafx.event.ActionEvent;
    import javafx.event.EventHandler;
    import javafx.scene.Group;
    import javafx.scene.Node;
    import javafx.scene.chart.Axis;
    import javafx.scene.chart.CategoryAxis;
    import javafx.scene.chart.XYChart;
    import javafx.scene.layout.Region;
    import javafx.scene.text.Text;
    import javafx.util.Duration;
     
    public class HisTChart extends XYChart <Date, String> {
     
        // CONSTRUCTEUR
        public HisTChart(Axis<Date> xAxis, Axis<String> yAxis) {
            super(xAxis, yAxis);
     
        }
     
        // METHODES HERITEES de XYCHART
     
        @Override
        protected void dataItemAdded(Series<Date, String> series, int itemIndex, Data<Date, String> item) {
           Node timeRegion = createTimeRegion(getData().indexOf(series), item, itemIndex);
            if (shouldAnimate()) {
                timeRegion.setOpacity(0);
                getPlotChildren().add(timeRegion);
                // Effet de transition en fade in
                FadeTransition ft = new FadeTransition(Duration.millis(500), timeRegion);
                ft.setToValue(1);
                ft.play();
            } else {
                // Pas d'effet
                getPlotChildren().add(timeRegion);
            }
        }
     
        @Override
        protected void dataItemRemoved(Data<Date, String> item, Series<Date, String> series) {
            final Node timeRegion = item.getNode();
            if (shouldAnimate()) {
                // suppression en fade out
                FadeTransition ft = new FadeTransition(Duration.millis(500), timeRegion);
                ft.setToValue(0);
                ft.setOnFinished(new EventHandler<ActionEvent>() {
                    @Override public void handle(ActionEvent actionEvent) {
                        getPlotChildren().remove(timeRegion);
                    }
                });
                ft.play();
            } else {
                // suppression barbare !
                getPlotChildren().remove(timeRegion);
            }
        }
     
        @Override
        protected void dataItemChanged(Data<Date, String> data) {
            throw new UnsupportedOperationException("Not supported yet.");.
        }
     
        @Override
        protected void seriesAdded(Series<Date, String> series, int seriesIndex) {
            for (int j=0; j<series.getData().size(); j++) {
                Data item = series.getData().get(j);
                Node timeRegion = createTimeRegion(seriesIndex, item, j);
                if (shouldAnimate()) {
                    timeRegion.setOpacity(0);
                    getPlotChildren().add(timeRegion);
                    //effet animé fade in
                    FadeTransition ft = new FadeTransition(Duration.millis(500),timeRegion);
                    ft.setToValue(1);
                    ft.play();
                } else {
                    getPlotChildren().add(timeRegion);
                }
            }
        }
     
        @Override
        protected void seriesRemoved(Series<Date, String> series) {
            for (XYChart.Data<Date, String> d : series.getData()) {
                final Node timeRegion = d.getNode();
                if (shouldAnimate()) {
                    // fade out encore
                    FadeTransition ft = new FadeTransition(Duration.millis(500),timeRegion);
                    ft.setToValue(0);
                    ft.setOnFinished(new EventHandler<ActionEvent>() {
                        @Override public void handle(ActionEvent actionEvent) {
                            getPlotChildren().remove(timeRegion);
                        }
                    });
                    ft.play();
                } else {
                    getPlotChildren().remove(timeRegion);
                }
            }
        }
     
        /* Cette méthode qui suit est appelée à chaque fois qu'il faut redessiner et repositionner les "Children". 
        Cela inclue toutes les opérations nécessaires à l'affichage des Nodes. */
     
        @Override
        protected void layoutPlotChildren() {
            // si pas de data, pas de layout
            if(getData() == null) return;
     
            // sinon, update des timeRegions
            for (int seriesIndex=0; seriesIndex < getData().size(); seriesIndex++) {
                Series<Date,String> series = getData().get(seriesIndex);
                Iterator<Data<Date,String>> iter = getDisplayedDataIterator(series);
     
                while(iter.hasNext()) {
                    // récupération de l'item
                    Data<Date, String> item = iter.next();
     
                    // récupération des positions des ses valeurs x, y et extravalue
                    double x = getXAxis().getDisplayPosition(getCurrentDisplayedXValue(item));
                    System.out.println("display Position x = " + x);
                    double y = getYAxis().getDisplayPosition(getCurrentDisplayedYValue(item));
                    System.out.println("display position y = " + y);
                    TimeRegionExtraValues extra = (TimeRegionExtraValues)item.getExtraValue();
     
                    //récupération de son Node associé
                    Node itemNode = item.getNode();
     
                    //si l'item a déjà un Node de type TimeRegion, on met à jour ce TimeRegion
                    if (itemNode instanceof TimeRegion && extra != null) {
                        TimeRegion timeRegion = (TimeRegion) itemNode;
     
                        double dateEnd = getXAxis().getDisplayPosition(extra.getDateEnd());
                        System.out.println("display position dateEnd = " + dateEnd);
     
                        // détermination de la hauteur d'un timeRegion
                        CategoryAxis yAxis = (CategoryAxis)getYAxis();
                        double timeRegionHeight = yAxis.getCategorySpacing() * 0.90; // 90% de l'écart entre catégories
                        System.out.println("timeRegionHeight = " + timeRegionHeight);
     
                        // màj de la timeRegion (largeur, hauteur)
                        timeRegion.update((dateEnd-x), timeRegionHeight);
     
                        // positionnement de la timeRegion
                        timeRegion.setLayoutX(x);
                        timeRegion.setLayoutY(y-(timeRegionHeight/2));
     
                    }
     
                }
            }
        }
     
        /**
         * Créer un nouveau Node TimeRegion pour un item
         *
         * @param seriesIndex index de la série dans laquelle se trouve l'item
         * @param item        item pour lequel créer la TimeRegion
         * @param itemIndex   index de l'item dans la série
         * @return Nouveau Node pour représenter l'item
         */
        private Node createTimeRegion(int seriesIndex, final Data item, int itemIndex) {
     
            Node timeRegion = item.getNode();
     
            // Vérifier si timeRegion n'est pas déjà créée
            if (timeRegion instanceof TimeRegion) {
     
                ((TimeRegion) timeRegion).setSeriesAndDataStyleClasses("series" + seriesIndex, "data" + itemIndex);
     
            } else {
     
                timeRegion = new TimeRegion("series" + seriesIndex, "data" + itemIndex);
                item.setNode(timeRegion);
     
            }
            return timeRegion;
        }
     
        private static class TimeRegion extends Group {
            private String seriesStyleClass;
            private String dataStyleClass;
            private Region tRegion = new Region();
            private Text tText = new Text();
     
            public TimeRegion(String seriesStyleClass, String dataStyleClass) {
                setAutoSizeChildren(false);
                getChildren().addAll(tRegion, tText);
                this.seriesStyleClass = seriesStyleClass;
                this.dataStyleClass = dataStyleClass;
                updateStyleClasses();
                        }
     
            public void update(double tRegionWidth, double tRegionHeight) {
     
                updateStyleClasses();
                tRegion.resizeRelocate(tRegionWidth/2, tRegionHeight/2, tRegionWidth, tRegionHeight);
                tText.setText("Test !!!");
     
            }
     
            public void setSeriesAndDataStyleClasses(String seriesStyleClass , String dataStyleClass) {
                this.seriesStyleClass = seriesStyleClass;
                this.dataStyleClass = dataStyleClass;
                updateStyleClasses();
            }
     
            private void updateStyleClasses() {
                getStyleClass().setAll("TimeRegion-timeRegion",seriesStyleClass,dataStyleClass);
                tText.getStyleClass().setAll("TimeRegion-tText",seriesStyleClass,dataStyleClass);
                tRegion.getStyleClass().setAll("IimeRegion-tRegion",seriesStyleClass,dataStyleClass);
            }
     
        }
     
        public static class TimeRegionExtraValues {
            private Date dateEnd;
            private String title;
     
            public TimeRegionExtraValues(Date dateEnd, String title) {
                this.dateEnd = dateEnd;
                this.title = title;
            }
     
            public Date getDateEnd() {
                return dateEnd;
            }
     
            public String getTitle() {
                return title;
            }
        }
     
    }
    Et le fichier histime.css

    Code css : 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
     
    @charset "utf-8";
    /* CSS Document */
     
    .chart-plot-background { 
    	-fx-background-color: transparent; 
    }
     
    .TimeRegion-timeRegion {
    	-fx-effect: dropshadow( two-pass-box , rgba(0,0,0,0.4) , 10, 0.0 , 2 , 4 );
    }
     
    .TimeRegion-tRegion {
        -fx-background-color: red;
    }
     
    .TimeRegion-tText {
    	-fx-font-weight: bold; 
    }

    J'espère que mes précisions ne vous embrouillent pas plus qu'elles ne vous éclairent...

    Donc voilà, si vous pouviez m'éclairer de vos lumières pour savoir pourquoi la Region tRegion ne s'affiche pas alors que la TimeRegion qui la contient s'affiche bien, je suis preneur ! Mon coiffeur vous en sera reconnaissant ! ^^

    D'avance merci pour le temps que vous passerez à y réfléchir.

    Cordialement.

  4. #4
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 900
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 900
    Billets dans le blog
    54
    Par défaut
    On va commencer molo :
    • Pas la peine de créer plusieurs fois des sujets similaires pour la même question.
    • Vu que tu ne l'a pas donne, J'ai du trouver une implémentation de DateAxis sur le net donc je ne sais pas si tout s'affiche comme ça le devrait (j'ai du entre autre désactiver l'appel setZoomFactor() et setRangeOnCenteredDate()).
    • Il existe un mode plein ecran donc une partie des manip que tu fais sur le Stage me semble inutile.
    • Un gestionnaire de mise en page tel que StackPane peut replacer avantageusement ton Group racine et donc éviter également tes manipulations sur la taille du graphe.
    • Utiliser ScenicView permet d'inspecter le contenu de la scene de de voir que tes zones sont bien présentes même si invisibles.

      Nom : histchart.jpg
Affichages : 1005
Taille : 103,6 Ko
    • Dans ton CSS tu as TimeRegion-tRegion, mais en fait le style mis dans ton code est IimeRegion-tRegion (avec un i et non pas un t) et donc c'est normal que des zones ne s'affichent pas en rouge.

      Nom : histchart2.jpg
Affichages : 921
Taille : 24,6 Ko
    • Cependant leur positionnement et leur taille ne semblent pas etre corrects.
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  5. #5
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2014
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2014
    Messages : 11
    Par défaut
    Désolé pour le double post, comme je te l'ai indiqué par MP, il y avait un petit soucis : aucun des deux messages n'apparaissait sur le forum.

    Pensant que le premier post avait été supprimé car manquant de formalisme et/ou étant un peu sec (j'avoue l'avoir à chaud après m'être arraché les cheveux ), j'en ai envoyé un second, un peu plus complet, précis et cordial (j'espère).
    En tout cas, merci beaucoup d'y avoir jeté un œil !


    • Je suis un peu novice en java donc je ne connais pas bien toutes les méthodes réglementaires pour la mise en page. En effet, mes instructions pour mettre en plein écran et positionner mes noeuds sont pas optimales. Je fais un peu à la débrouille mais je vais revoir ça.
    • Le DateAxis, j'ai pas voulu donner l'implémentation, j'ai préféré citer les blogs qui m'ont aidé pour citer les auteurs originaux. Ceci dit, il fonctionne grosso modo comme un Axis standard. J'y ai seulement ajouté deux ou trois choses pour gérer le range différemment.
    • Le problème venait donc d'une bête faute de frappe... Ok... Ce "I" s'affichait presque comme un "T" sur mon écran. Je l'ai pas vu passer.
    • Je n'utilisais pas ScenicView jusque là. On ne m'y reprendra plus J'avais ajouté des println() de ci de là pour vérifier à la console que tout se passait bien.


    Merci beaucoup en tout cas ! Ca marche !

    J'ai plus qu'à corriger toutes les imperfections.
    (L'erreur de positionnement vient de la ligne 201 d'HisTChart.java
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    tRegion.resizeRelocate(0, 0, tRegionWidth, tRegionHeight);
    ... maintenant c'est bon.)

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

Discussions similaires

  1. [JavaFX] (Débutant) Problème d'affichage d'un menu
    Par mikl_apo dans le forum JavaFX
    Réponses: 3
    Dernier message: 31/03/2009, 21h25
  2. Réponses: 1
    Dernier message: 06/11/2008, 14h58
  3. Pb affichage avec un PaintBox (pour eviter scintillement)
    Par juan64 dans le forum C++Builder
    Réponses: 7
    Dernier message: 08/04/2004, 09h21
  4. probléme d'affichage d'une fiche
    Par sb dans le forum Composants VCL
    Réponses: 7
    Dernier message: 29/08/2002, 09h43
  5. Affichage en passant par un buffer...
    Par Sirotilc dans le forum MFC
    Réponses: 5
    Dernier message: 27/05/2002, 21h00

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