在JavaFX中堆叠图表

时间:2015-02-28 23:16:58

标签: javafx javafx-8 bar-chart linechart

我在JavaFX中使用BarChart和LineChart。当我将两个图表制作成相同尺寸并将它们放在同一个地方时,它们会完美地相互重叠。如何让LineChart显示在BarChart的顶部。

目前我一直将不透明度设置为0.7,因此他们看起来很好看'但显然这不是一条路。

2 个答案:

答案 0 :(得分:7)

Jewelsea发布了example on a gist

它基本上归结为使用StackPane来堆叠图表并修改所有叠加层的可见性。

这是一个更简单的修改版本,我如何使用它:

public class StackedChartSample extends Application {

    final static String austria = "Austria";
    final static String brazil = "Brazil";
    final static String france = "France";
    final static String italy = "Italy";
    final static String usa = "USA";

    @Override
    public void start(Stage stage) {

        final CategoryAxis xAxis = new CategoryAxis();
        final NumberAxis yAxis = new NumberAxis();

        // base chart
        final BarChart<String, Number> barChart = new BarChart<String, Number>(xAxis, yAxis);
        barChart.setLegendVisible(false);
        barChart.setAnimated(false);

        xAxis.setLabel("Country");
        yAxis.setLabel("Value");

        // overlay chart
        LineChart<String, Number> lineChart = new LineChart<String, Number>(xAxis, yAxis);
        lineChart.setLegendVisible(false);
        lineChart.setAnimated(false);
        lineChart.setCreateSymbols(true);
        lineChart.setAlternativeRowFillVisible(false);
        lineChart.setAlternativeColumnFillVisible(false);
        lineChart.setHorizontalGridLinesVisible(false);
        lineChart.setVerticalGridLinesVisible(false);
        lineChart.getXAxis().setVisible(false);
        lineChart.getYAxis().setVisible(false);
        lineChart.getStylesheets().addAll(getClass().getResource("chart.css").toExternalForm());

        barChart.getData().add( createChartSeries());
        lineChart.getData().add( createChartSeries());

        StackPane root = new StackPane();
        root.getChildren().addAll( barChart, lineChart);

        Scene scene = new Scene(root, 800, 600);

        stage.setScene(scene);
        stage.show();
    }

    private XYChart.Series<String,Number> createChartSeries() {

        XYChart.Series<String,Number> series = new XYChart.Series<String,Number>();
        series.getData().add(new XYChart.Data<String,Number>(austria, 25601.34));
        series.getData().add(new XYChart.Data<String,Number>(brazil, 20148.82));
        series.getData().add(new XYChart.Data<String,Number>(france, 10000));
        series.getData().add(new XYChart.Data<String,Number>(italy, 35407.15));
        series.getData().add(new XYChart.Data<String,Number>(usa, 12000));

        return series;
    }


    public static void main(String[] args) {
        launch(args);
    }
}

chart.css

.chart-plot-background {
-fx-background-color: transparent;
}
.default-color0.chart-series-line {
-fx-stroke: blue;
} 
.default-color0.chart-line-symbol { 
    -fx-background-color: blue, white;
}

答案 1 :(得分:3)

我没有足够的声誉&#34;在 Roland 的回答下添加评论,但我担心提议的解决方案存在问题。

1)如果第二个系列的值不相同,则y轴会适应它们的范围,但第一个图表的高度不适应。

下面的例子:第一个橙色条的值是25,601:它应该不那么高。

enter image description here

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.chart.BarChart;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class Exemple158_JavaFX_Overlaid_Stacked_Charts extends Application {

final static String AUSTRIA = "Austria";
final static String BRAZIL = "Brazil";
final static String FRANCE = "France";
final static String ITALY = "Italy";
final static String USA = "USA";


@Override
public void start(Stage stage) {

    // x-axis and y-axis  for both charts:
    final CategoryAxis xAxis = new CategoryAxis();
    xAxis.setLabel("Country");
    final NumberAxis yAxis1 = new NumberAxis();
    yAxis1.setLabel("Value");

    // first chart:
    final BarChart<String, Number> barChart = new BarChart<>(xAxis, yAxis1);
    barChart.setLegendVisible(false);
    barChart.setAnimated(false);
    XYChart.Series<String, Number> series1 = new XYChart.Series<>();
    series1.getData().add(new XYChart.Data<>(AUSTRIA, 25601.34));
    series1.getData().add(new XYChart.Data<>(BRAZIL, 20148.82));
    series1.getData().add(new XYChart.Data<>(FRANCE, 10000));
    series1.getData().add(new XYChart.Data<>(ITALY, 35407.15));
    series1.getData().add(new XYChart.Data<>(USA, 12000));
    barChart.getData().add(series1);

    // second chart (overlaid):
    final LineChart<String, Number> lineChart = new LineChart<>(xAxis, yAxis1);
    lineChart.setLegendVisible(false);
    lineChart.setAnimated(false);
    lineChart.setCreateSymbols(true);
    lineChart.setAlternativeRowFillVisible(false);
    lineChart.setAlternativeColumnFillVisible(false);
    lineChart.setHorizontalGridLinesVisible(false);
    lineChart.setVerticalGridLinesVisible(false);
    lineChart.getXAxis().setVisible(false);
    lineChart.getYAxis().setVisible(false);
    lineChart.getStylesheets().addAll(getClass().getResource("Exemple158.css").toExternalForm());
    XYChart.Series<String, Number> series2 = new XYChart.Series<>();
    int delta = 10000;
    series2.getData().add(new XYChart.Data<>(AUSTRIA, 25601.34 + delta));
    series2.getData().add(new XYChart.Data<>(BRAZIL, 20148.82 + delta));
    series2.getData().add(new XYChart.Data<>(FRANCE, 10000 + delta));
    series2.getData().add(new XYChart.Data<>(ITALY, 35407.15 + delta));
    series2.getData().add(new XYChart.Data<>(USA, 12000 + delta));
    lineChart.getData().add(series2);

    StackPane root = new StackPane();
    root.getChildren().addAll(barChart, lineChart);
    Scene scene = new Scene(root, 800, 600);
    stage.setScene(scene);
    stage.show();
}

public static void main(String[] args) {
    launch(args);
}
}

CSS:

.chart-plot-background {
-fx-background-color: transparent;
}

.default-color0.chart-series-line {
-fx-stroke: blue;
}

.default-color0.chart-line-symbol { 
-fx-background-color: blue, white;
}

2)解决方案是从头开始设置y轴的边界:

final NumberAxis yAxis1 = new NumberAxis(0, 48000, 5000);

enter image description here