3 Replies Latest reply: Mar 12, 2013 8:03 PM by jsmith RSS

    how to add 3 legends for a single series barchart?? JAVAFX

    HassanShakeel
      Here is my code to generate 10 bars of different colors. I want to add legend respectively but it only one shows yellow legend

      1. I think it shows only 1 color because there is only 1 series. Is it possible to add more than 1 legend for a single series?

      or

      2. or can i display another image for legend in barchart??

      output :http://i.stack.imgur.com/fSNu7.png

      file i want to display in barchart:http://i.stack.imgur.com/cchch.png
      ..
      public class DynamicallyColoredBarChart extends Application {
      
          @Override
          public void start(Stage stage) {
              final CategoryAxis xAxis = new CategoryAxis();
              xAxis.setLabel("Bars");
              final NumberAxis yAxis = new NumberAxis();
              yAxis.setLabel("Value");
      
              final BarChart<String, Number> bc = new BarChart<>(xAxis, yAxis);
              bc.setLegendVisible(false);
      
              XYChart.Series series1 = new XYChart.Series();
      
              for (int i = 0; i < 10; i++) {
                  // change color of bar if value of i is >5 than red if i>8 than blue
                  final XYChart.Data<String, Number> data = new XYChart.Data("Value " + i, i);
                  data.nodeProperty().addListener(new ChangeListener<Node>() {
                      @Override
                      public void changed(ObservableValue<? extends Node> ov, Node oldNode, Node newNode) {
                          if (newNode != null) {
                              if (data.getYValue().intValue() > 8) {
                                  newNode.setStyle("-fx-bar-fill: navy;");
                              } else if (data.getYValue().intValue() > 5) {
                                  newNode.setStyle("-fx-bar-fill: red;");
                              }
                          }
                      }
                  });
                  series1.getData().add(data);
              }
              bc.getData().add(series1);
              stage.setScene(new Scene(bc));
              stage.show();
          }
      
          public static void main(String[] args) {
              launch(args);
          }
      }
      ...
      Edited by: 993431 on Mar 12, 2013 1:42 PM
        • 1. Re: how to add 3 legends for a single series barchart?? JAVAFX
          jsmith
          Either:
          1. Use a chart which displays multiple series, then you can allow the built-in legend to show OR
          2. Use a single dynamically colored series have you have done and create your own custom legend.
          import javafx.application.Application;
          import javafx.scene.*;
          import javafx.scene.chart.*;
          import javafx.stage.Stage;
          
          public class ThreeSeriesBarChart extends Application {
            @Override public void start(Stage stage) {
              final CategoryAxis xAxis = new CategoryAxis();
              xAxis.setLabel("Bars");
              final NumberAxis yAxis = new NumberAxis();
              yAxis.setLabel("Value");
          
              final BarChart<String, Number> bc = new BarChart<>(xAxis, yAxis);
              XYChart.Series lowSeries = new XYChart.Series();
              lowSeries.setName("Not Achieved");
              XYChart.Series medSeries = new XYChart.Series();
              medSeries.setName("Achieved");
              XYChart.Series hiSeries  = new XYChart.Series();
              hiSeries.setName("Exceeded");
              bc.setBarGap(0);
              bc.setCategoryGap(0);
          
              for (int i = 0; i < 10; i++) {
                final XYChart.Data<String, Number> data = new XYChart.Data("Value " + i, i);
                if (data.getYValue().intValue() > 8) {
                  hiSeries.getData().add(data);
                } else if (data.getYValue().intValue() > 5) {
                  medSeries.getData().add(data);
                } else {
                  lowSeries.getData().add(data);
                }
              }
              bc.getData().setAll(lowSeries, medSeries, hiSeries);
              
              bc.getStylesheets().add(getClass().getResource("colored-chart.css").toExternalForm());
              
              stage.setScene(new Scene(bc));
              stage.show();
            }
          
            public static void main(String[] args) {
              launch(args);
            }
          }
          import javafx.application.Application;
          import javafx.beans.value.*;
          import javafx.geometry.Pos;
          import javafx.scene.*;
          import javafx.scene.chart.*;
          import javafx.scene.control.Label;
          import javafx.scene.layout.*;
          import javafx.scene.paint.Color;
          import javafx.scene.shape.*;
          import javafx.stage.Stage;
          
          public class DynamicallyColoredBarChart extends Application {
            @Override public void start(Stage stage) {
              final CategoryAxis xAxis = new CategoryAxis();
              xAxis.setLabel("Bars");
              final NumberAxis yAxis = new NumberAxis();
              yAxis.setLabel("Value");
          
              final BarChart<String, Number> bc = new BarChart<>(xAxis, yAxis);
              bc.setLegendVisible(false);
          
              XYChart.Series series1 = new XYChart.Series();
          
              for (int i = 0; i < 10; i++) {
                // change color of bar if value of i is >5 than red if i>8 than blue
                final XYChart.Data<String, Number> data = new XYChart.Data("Value " + i, i);
                data.nodeProperty().addListener(new ChangeListener<Node>() {
                  @Override
                  public void changed(ObservableValue<? extends Node> ov, Node oldNode, Node newNode) {
                    if (newNode != null) {
                      if (data.getYValue().intValue() > 8) {
                        newNode.setStyle("-fx-bar-fill: -fx-exceeded;");
                      } else if (data.getYValue().intValue() > 5) {
                        newNode.setStyle("-fx-bar-fill: -fx-achieved;");
                      } else {
                        newNode.setStyle("-fx-bar-fill: -fx-not-achieved;");
                      }
                    } 
                  }
                });
                series1.getData().add(data);
              }
              bc.getData().add(series1);
          
              LevelLegend legend = new LevelLegend();
              legend.setAlignment(Pos.CENTER);
          
              VBox chartWithLegend = new VBox();
              chartWithLegend.getChildren().setAll(bc, legend);
              
              chartWithLegend.getStylesheets().add(getClass().getResource("colored-chart.css").toExternalForm());
              
              stage.setScene(new Scene(chartWithLegend));
              stage.show();
            }
            
            class LevelLegend extends GridPane {
              LevelLegend() {
                setHgap(10);
                setVgap(10);
                addRow(0, createSymbol("-fx-exceeded"),     new Label("Exceeded"));
                addRow(1, createSymbol("-fx-achieved"),     new Label("Achieved"));
                addRow(2, createSymbol("-fx-not-achieved"), new Label("Not Achieved"));
                
                getStyleClass().add("level-legend");
              }
              
              private Node createSymbol(String fillStyle) {
                Shape symbol = new Ellipse(10, 5, 10, 5);
                symbol.setStyle("-fx-fill: " + fillStyle);
                symbol.setStroke(Color.BLACK);
                symbol.setStrokeWidth(2);
                
                return symbol;
              }
            }
          
            public static void main(String[] args) { launch(args); }
          }
          /** colored-chart.css: place in same directory as other bar chart application files and setup your build system to copy it to the output directory */
          .root {
            -fx-not-achieved: red;
            -fx-achieved:     green;
            -fx-exceeded:     blue;
          }
          
          .default-color0.chart-bar { -fx-bar-fill: -fx-not-achieved; }
          .default-color1.chart-bar { -fx-bar-fill: -fx-achieved; }
          .default-color2.chart-bar { -fx-bar-fill: -fx-exceeded; }
          
          .level-legend {
            -fx-padding: 10; 
            -fx-border-width: 2; 
            -fx-background-color: rgba(211, 211, 211, 0.5); 
            -fx-border-color: derive(rgba(211, 211, 211, 0.7), 10%);
          }
          • 2. Re: how to add 3 legends for a single series barchart?? JAVAFX
            HassanShakeel
            Thank you so much your code works .. 1 more question is it possible to add value label of each bar on top of each bar??
            and again thanks :)
            • 3. Re: how to add 3 legends for a single series barchart?? JAVAFX
              jsmith
              is it possible to add value label of each bar on top of each bar
              Yes, see: "how to display bar value on top of bar javafx"
              http://stackoverflow.com/questions/15237192/how-to-display-bar-value-on-top-of-bar-javafx/15375168