Charts: How to correlate colors between charts?

后端 未结 2 1129
南旧
南旧 2021-01-06 04:38

Below is an example that

  • has two charts visualizing the same set of data
  • while the data are the same, their sequence differs (in rw code that would ha
相关标签:
2条回答
  • 2021-01-06 05:07

    Got it working, here's the code:

    public class CorrelatedChartColors extends Application {
    
    @Override
    public void start(Stage primaryStage) {
        PieChart pieChart = new PieChart();
        pieChart.setData(getPieData());
    
        final CategoryAxis xAxis = new CategoryAxis();
        final NumberAxis yAxis = new NumberAxis();
        final StackedBarChart<String, Number> sbc =
                new StackedBarChart<>(xAxis, yAxis);
        xAxis.setCategories(FXCollections.<String> observableArrayList(Arrays.asList("Programming Languages Usage in %")));
    
        XYChart.Series<String, Number> series1 = new XYChart.Series();
        XYChart.Series<String, Number> series2 = new XYChart.Series();
        XYChart.Series<String, Number> series3 = new XYChart.Series();
        XYChart.Series<String, Number> series4 = new XYChart.Series();
        XYChart.Series<String, Number> series5 = new XYChart.Series();
    
        series1.setName("Java");
        series2.setName("C");
        series3.setName("PHP");
        series4.setName("(Visual)Basic");
        series5.setName("Other");
    
        series1.getData().add(new XYChart.Data("Programming Languages Usage in %", 17.56));
        series2.getData().add(new XYChart.Data<>("Programming Languages Usage in %", 17.06));
        series3.getData().add(new XYChart.Data<>("Programming Languages Usage in %", 6.0));
        series4.getData().add(new XYChart.Data<>("Programming Languages Usage in %", 4.76));
        series5.getData().add(new XYChart.Data<>("Programming Languages Usage in %", 31.37));
    
        sbc.getData().addAll(series1, series2, series3, series4, series5);
        primaryStage.setTitle("Correlated Charts");
        Scene scene = new Scene(new HBox(pieChart, sbc));
        scene.getStylesheets().add(CorrelatedChartColors.class.getResource("chartStyles.css").toExternalForm());
        primaryStage.setScene(scene);
        primaryStage.show();
    }
    
    /**
     * Creates and returns data for StackedBarChart from the given pieData.
     */
    @SuppressWarnings("unchecked")
    private ObservableList<Series<String, Number>> createBarData(
            ObservableList<Data> pieChartData) {
        ObservableList<Series<String, Number>> data = pieChartData.stream()
            .map(p -> new XYChart.Data<>("none", (Number) p.getPieValue(), p.getName())) 
            .map(xy -> new Series<>((String)xy.getExtraValue(), 
                        FXCollections.observableArrayList(xy)))
            .collect(toObservableList())
        ;
        return data;
    }
    
    /**
     * Creates and returns data for PieChart.
     */
    private ObservableList<Data> getPieData() {
        ObservableList<Data> pieData = FXCollections.observableArrayList();
        pieData.addAll(new PieChart.Data("java", 17.56), 
                new PieChart.Data("C", 17.06), 
                new PieChart.Data("PHP", 6.0),
                new PieChart.Data("(Visual)Basic", 4.76),
                new PieChart.Data("Other", 31.37));
        return pieData;
    }
    
    public static <T>  Collector<T, ?, ObservableList<T>> toObservableList() {
        return Collector.of((Supplier<ObservableList<T>>) FXCollections::observableArrayList,
                ObservableList::add,
                (left, right) -> {
                    left.addAll(right);
                    return left;
                });
    }
    
    public static void main(String[] args) {
        launch(args);
    }
    }
    

    and then the code for the CSS file:

    .default-color3.chart-bar {
    -fx-bar-fill: black;
    }
    
    .default-color0.chart-pie {
    -fx-pie-color: black;
    }
    

    Now you can change the color of every bar in either one of the 2 charts. If you want to change the color of the top bar, simply add a new css entry

    .default-color0.chart-bar {
    -fx-bar-fill: green;
    }
    
    0 讨论(0)
  • 2021-01-06 05:13

    I just changed some stuff in the start method (plus some imports I'm sure). I don't think this is the best way. I would make a stylesheet in user.dir and write my colors there with names like java-color etc., then use that for the default chart colors.

    @Override
    public void start(Stage primaryStage) {
        PieChart pieChart = new PieChart();
        pieChart.setData(getPieData());
        final HashMap<String, Integer> colors = new HashMap<>();
        pieChart.getData().stream().forEach((pd)->{
            colors.put(pd.getName(), pieChart.getData().indexOf(pd));
        });
    
        final CategoryAxis xAxis = new CategoryAxis(FXCollections.observableArrayList("none"));
        final NumberAxis yAxis = new NumberAxis();
        final StackedBarChart<String, Number> sbc =
                new StackedBarChart<>(xAxis, yAxis);
        ObservableList<Series<String, Number>> barData = createBarData(getPieData());
        // simulate client code that re-orders/filters the data
        FXCollections.shuffle(barData);
        sbc.setData(barData);
    
        primaryStage.setTitle("Correlated Charts");
        Scene scene = new Scene(new HBox(pieChart, sbc));
        primaryStage.setScene(scene);
        primaryStage.show();
    
        //can only get nodes after charts are drawn
        barData.stream().forEach((bd)->{
            int num = colors.get(bd.getName());
            //eg. chart-bar series1 data0 default-color1
            bd.getData().get(0).getNode().getStyleClass().setAll("chart-bar","series"+num,"data0","default-color"+num);
        });
    
        Legend legend = (Legend)sbc.lookup(".chart-legend");
        legend.getChildrenUnmodifiable().stream().forEach((l)->{
            Label label = (Label)l;
            Node n = label.getGraphic();
            int num = colors.get(label.getText());
            //eg. chart-legend-item-symbol chart-bar series1 bar-legend-symbol default-color1
            n.getStyleClass().setAll("chart-legend-item-symbol","chart-bar","series"+num,"bar-legend-symbol","default-color"+num);
        });
    }
    

    here's proof

    0 讨论(0)
提交回复
热议问题