Charts: How to correlate colors between charts?

試著忘記壹切 提交于 2019-12-04 12:53:32

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);
    });
}

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;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!