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 :

Comment récupérer la couleur d'un slice de pie chart au runtime.


Sujet :

JavaFX

  1. #1
    Candidat au Club
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2017
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Février 2017
    Messages : 2
    Par défaut Comment récupérer la couleur d'un slice de pie chart au runtime.
    Bonjour,

    Je voudrais récupérer la couleur d'un slice de pie chart pour colorer un autre élément graphique.

    J'ai pu contourner le problème en imposant les couleurs des slices dans le css :

    .data0.chart-pie { -fx-pie-color: turquoise; }
    .data1.chart-pie { -fx-pie-color: red; }
    ....
    et en redéfinissant d'autres styles que je peux appliquer
    .PhFillColor-0 { -fx-fill:turquoise; }
    .PhFillColor-1 { -fx-fill:red; }
    ...

    Au runtime je récupère le style du slice je fais la correspondance .dataX.chart-pie avec le style perso .PhFillColor-X que j'ai défini,puis je l'applique à mon objet graphique.

    J'ai terminé mon dev et le résultat est conforme fonctionnellement.
    Néanmoins ce n'est pas très satisfaisant
    1 - d'avoir à redéfinir les couleurs par défaut des slices
    2 - de maintenir une correspondance des deux "tableaux" de styles CSS.

    Quel moyen aurais-je du employer?
    Merci de vos lumières.

  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
    Je dirai en faisant un lookup sur son id ou en récupérant directement le nœud sur le data approprie. Mais il faudra attendre que le graphe soit visible.
    Par contre tu ne vas pas forcement récupérer une couleur, tu vas récupérer un Background qui remplit la région utilisée pour rendre le secteur/part de tarte. Donc il va falloir explorer plus en avant.
    Un Background peut être composé de plusieurs BackgroundFill superposés (par défaut il n'y en a qu'un), eux-mêmes contenant un Paint qui peut être soit une couleur unie, un gradient linéaire, un gradient radial ou même une texture (que j'ai pas testé ici). Évidement dans le cas des gradients tu te retrouves avec plusieurs couleurs en fonction des stops qui les composent.

    Sinon j'ai absolument aucune idee s'il est possible de retrouver les valeurs/sélecteurs mises sur le CSS.

    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
    package piecolor;
     
    import java.util.List;
    import java.util.stream.IntStream;
    import javafx.application.Application;
    import javafx.application.Platform;
    import javafx.geometry.Insets;
    import javafx.scene.Node;
    import javafx.scene.Scene;
    import javafx.scene.chart.PieChart;
    import javafx.scene.control.Dialog;
    import javafx.scene.control.Label;
    import javafx.scene.control.Tooltip;
    import javafx.scene.layout.Background;
    import javafx.scene.layout.BackgroundFill;
    import javafx.scene.layout.CornerRadii;
    import javafx.scene.layout.HBox;
    import javafx.scene.layout.Priority;
    import javafx.scene.layout.Region;
    import javafx.scene.layout.StackPane;
    import javafx.scene.layout.VBox;
    import javafx.scene.paint.Color;
    import javafx.scene.paint.LinearGradient;
    import javafx.scene.paint.Paint;
    import javafx.scene.paint.RadialGradient;
    import javafx.scene.paint.Stop;
    import javafx.scene.shape.Rectangle;
    import javafx.stage.Modality;
    import javafx.stage.Stage;
     
    public final class Main extends Application {
     
        final static int MIN_SERIES_NUMBER = 2;
        final static int MAX_SERIES_NUMBER = 5;
        final static int MAX_SERIES_VALUE = 10;
     
        private PieChart createChart() {
            final int seriesCount = (int) Math.max(MIN_SERIES_NUMBER, MAX_SERIES_NUMBER * Math.random());
            final PieChart chart = new PieChart();
            IntStream.range(0, seriesCount)
                    .mapToObj(index -> {
                        final String name = String.format("Serie %d", index + 1);
                        final double value = MAX_SERIES_VALUE * Math.random();
                        return new PieChart.Data(name, value);
                    })
                    .forEach(chart.getData()::add);
            return chart;
        }
     
        private PieChart pieChart;
     
        @Override
        public void start(final Stage primaryStage) {
            pieChart = createChart();
            final StackPane root = new StackPane();
            root.getChildren().add(pieChart);
            final Scene scene = new Scene(root, 600, 600);
            primaryStage.setTitle("Test");
            primaryStage.setScene(scene);
            primaryStage.show();
            Platform.runLater(this::findOutBackgrounds);
    //        ScenicView.show(scene);
        }
     
        private void findOutBackgrounds() {
            IntStream.range(0, pieChart.getData().size())
                    .forEach(this::findOutBackground);
     
        }
     
        private void findOutBackground(int seriesIndex) {
            final String selector = String.format(".data%d", seriesIndex);
            final Node node1 = pieChart.lookup(selector);
            final Node node2 = pieChart.getData().get(seriesIndex).getNode();
            assert (node1 != null);
            assert (node1 == node2);
            assert (node1 instanceof Region);
            Region region = (Region) node1;
            final Background background = region.getBackground();
            final Region backgroundArea = new Region();
            VBox.setVgrow(backgroundArea, Priority.ALWAYS);
            backgroundArea.setMinSize(500, 500);
            backgroundArea.setBackground(background);
            Tooltip.install(backgroundArea, new Tooltip("Series' background"));
            //
            final VBox root = new VBox();
            root.setFillWidth(true);
            final HBox fillRow = new HBox();
            VBox.setVgrow(fillRow, Priority.NEVER);
            final int fillNumber = background.getFills().size();
            IntStream.range(0, fillNumber)
                    .mapToObj(fillIndex -> {
                        final BackgroundFill fill = background.getFills().get(fillIndex);
                        final Paint paint = fill.getFill();
                        System.out.println(paint.getClass());
                        final Region fillArea = new Region();
                        fillArea.setMinSize(50, 50);
                        fillArea.setBackground(new Background(new BackgroundFill(paint, CornerRadii.EMPTY, Insets.EMPTY)));
                        Tooltip.install(fillArea, new Tooltip(String.format("Fill #%d", fillIndex)));
                        HBox.setHgrow(fillArea, Priority.NEVER);
                        return fillArea;
                    })
                    .forEach(fillRow.getChildren()::add);
            final Region filler1 = new Region();
            HBox.setHgrow(filler1, Priority.ALWAYS);
            fillRow.getChildren().add(filler1);
            root.getChildren().addAll(backgroundArea, fillRow);
            //
            IntStream.range(0, fillNumber)
                    .mapToObj(fillIndex -> {
                        final BackgroundFill fill = background.getFills().get(fillIndex);
                        final Paint paint = fill.getFill();
                        final HBox colorRow = new HBox();
                        VBox.setVgrow(colorRow, Priority.NEVER);
                        colorRow.getChildren().add(new Label(String.format("Fill #%d", fillIndex)));
                        if (paint instanceof Color) {
                            final Rectangle colorArea = new Rectangle(25, 25);
                            colorArea.setFill(paint);
                            Tooltip.install(colorArea, new Tooltip("Single color"));
                            colorRow.getChildren().add(colorArea);
                        } else if (paint instanceof LinearGradient || paint instanceof RadialGradient) {
                            final List<Stop> stops = (paint instanceof LinearGradient) ? ((LinearGradient) paint).getStops() : ((RadialGradient) paint).getStops();
                            final String gradientType = (paint instanceof LinearGradient) ? "Linear" : "Radial";
                            final int stopNumber = stops.size();
                            IntStream.range(0, stopNumber)
                                    .mapToObj(stopIndex -> {
                                        final Stop stop = stops.get(stopIndex);
                                        final Color color = stop.getColor();
                                        final Rectangle colorArea = new Rectangle(25, 25);
                                        colorArea.setFill(color);
                                        Tooltip.install(colorArea, new Tooltip(String.format("%s color #%d", gradientType, stopIndex)));
                                        return colorArea;
                                    })
                                    .forEach(colorRow.getChildren()::add);
                        }
                        return colorRow;
                    })
                    .forEach(root.getChildren()::add);
            final String title = String.format("%d - %s", seriesIndex, pieChart.getData().get(seriesIndex).getName());
            final Dialog dialog = new Dialog();
            dialog.setTitle(title);
            dialog.getDialogPane().setContent(root);
            dialog.initModality(Modality.NONE);
            dialog.initOwner(region.getScene().getWindow());
            dialog.show();
        }
     
        public static void main(String[] args) {
            launch(args);
        }
    }
    Nom : fills.jpg
Affichages : 570
Taille : 217,3 Ko
    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
    Candidat au Club
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2017
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Février 2017
    Messages : 2
    Par défaut MerciS
    Whaou ,
    Merci pour la rapidité de la réponse ....
    et surtout merci pour la qualité de cette réponse!

    J'y ai appris l'utilisation du background et en particulier que le même objet background est utilisable pour plusieurs région.
    que la couleur d'une part de camembert n'est pas uniforme mais un RadialGradient avec comme conséquence qu'il y a pas une mais deux couleurs, (bien qu'il n'y en ait qu'une seule définie par CSS et que visuellement cela reste assez discret).
    Qu'il est utile parfois de rechercher au delà des objets présentés par scenicview.

    je propose un autre code de ta méthode void findOutBackground(int seriesIndex) qui se limite à l'utilisation du même background et qui dans mon cas répond précisément à la problématique (sans parler de couleur finalement ):
    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
     private void findOutBackground(int seriesIndex) {
                Node lSliceNode = pieChart.getData().get(seriesIndex).getNode();
                Region lSliceRegion = (Region) lSliceNode;
                Background lSliceBackground = lSliceRegion.getBackground();
     
                Region lNewRegion2BColored = new Region();
                lNewRegion2BColored.setBackground(lSliceBackground);
     
                VBox.setVgrow(lNewRegion2BColored, Priority.ALWAYS);
                lNewRegion2BColored.setMinSize(500, 500);
                VBox root = new VBox();
                root.getChildren().add(lNewRegion2BColored);
     
                Dialog dialog = new Dialog();
                String title = String.format("%d - %s", seriesIndex, pieChart.getData().get(seriesIndex).getName());
                dialog.setTitle(title);
                dialog.getDialogPane().setContent(root);
                dialog.initModality(Modality.NONE);
                dialog.initOwner(lSliceRegion.getScene().getWindow());
                dialog.show();
            }

    Je pense qu'il manque à javafx de l'api pour récupérer les clés/valeurs CSS associées a un objet graphique, même si la solution que tu as proposé est plus élégante.
    J'ai apprécié la complétude de ta réponse, merci encore.

Discussions similaires

  1. Réponses: 3
    Dernier message: 27/06/2015, 17h12
  2. Réponses: 2
    Dernier message: 03/12/2014, 15h28
  3. TRichEdit : comment récupérer la couleur de fond, sous le curseur
    Par delphidebutant dans le forum Composants VCL
    Réponses: 1
    Dernier message: 12/07/2011, 18h49
  4. Réponses: 3
    Dernier message: 28/05/2009, 15h04
  5. Réponses: 2
    Dernier message: 20/12/2007, 15h43

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