对齐CategoryAxis和NumberAxis

时间:2017-04-01 13:21:27

标签: javafx javafx-8 bar-chart linechart

我目前正在使用JavaFX堆叠两个不同的图表(BarChart和LineChart)。 LineChart分为三个区域,以显示BarChart的点落入的位置。

我的当前代码存在问题,其中来自BarChart的CategoryAxis和来自LineChart的NumberAxis在xAxis上没有很好地对齐。 这就是目前的情况:

enter image description here

如您所见(单击要放大的图像),xAxis上的某些值不对齐。我无法对LineChart和BarChart使用相同的NumberAxis,因为BarChart仅支持CategoryAxis。有没有办法解决这个问题,以便沿xAx的值对齐?

代码:

    NumberAxis xAxis = new NumberAxis(0, 6, 1);
    xAxis.setLabel("X");

    NumberAxis yAxis = new NumberAxis(-5, 5, 0.5);
    yAxis.setLabel("Y");

    XYChart.Series<Number, Number> dataSeries1 = new XYChart.Series<>();
    XYChart.Series<Number, Number> dataSeries2 = new XYChart.Series<>();

    dataSeries1.setName("2SD");
    dataSeries2.setName("3SD");

    dataSeries1.getData().add(new XYChart.Data<>(0, 0.6));
    dataSeries1.getData().add(new XYChart.Data<>(1, 0.9));
    dataSeries1.getData().add(new XYChart.Data<>(2, 1.7));
    dataSeries1.getData().add(new XYChart.Data<>(3, 1.8));
    dataSeries1.getData().add(new XYChart.Data<>(4, 1.8));
    dataSeries1.getData().add(new XYChart.Data<>(5, 2.1));
    dataSeries1.getData().add(new XYChart.Data<>(6, 2.3));

    dataSeries2.getData().add(new XYChart.Data<>(0, 1.0));
    dataSeries2.getData().add(new XYChart.Data<>(1, 1.3));
    dataSeries2.getData().add(new XYChart.Data<>(2, 2.4));
    dataSeries2.getData().add(new XYChart.Data<>(3, 2.5));
    dataSeries2.getData().add(new XYChart.Data<>(4, 2.7));
    dataSeries2.getData().add(new XYChart.Data<>(5, 3.1));
    dataSeries2.getData().add(new XYChart.Data<>(6, 3.3));

    final LineChart<Number, Number> lineChart =
            new LineChart<Number, Number>(xAxis, yAxis, FXCollections.observableArrayList(dataSeries2, dataSeries1)) {
                @Override
                protected void layoutPlotChildren() {
                    super.layoutPlotChildren();

                    XYChart.Series a =  getData().get(0);
                    XYChart.Series b =  getData().get(1);
                    ObservableList<XYChart.Data<Number, Number>> aData = a.getData();
                    ObservableList<XYChart.Data<Number, Number>> bData = b.getData();

                    for(int i = 0; i < aData.size()-1; i++){

                        // Color in the area between 2SD and 3SD
                        double x = getXAxis().getDisplayPosition(aData.get(i).getXValue());
                        double y = getYAxis().getDisplayPosition(bData.get(i).getYValue());
                        double x2 = getXAxis().getDisplayPosition(aData.get((i+1)).getXValue());
                        double y2 = getYAxis().getDisplayPosition(bData.get((i+1)).getYValue());

                        Polygon middlePolygon = new Polygon();

                        middlePolygon.getPoints().addAll(x,y,
                                x, getYAxis().getDisplayPosition(aData.get(i).getYValue()),
                                x2,getYAxis().getDisplayPosition(aData.get((i+1)).getYValue()),
                                x2,y2);
                        getPlotChildren().add(middlePolygon);
                        middlePolygon.toFront();
                        middlePolygon.setFill(Color.ORANGE);

                        // Color in the area above 3SD
                        double y3 = getXAxis().getDisplayPosition(0);
                        double y4 = getXAxis().getDisplayPosition(0);

                        Polygon topPolygon = new Polygon();

                        topPolygon.getPoints().addAll(x,y3,
                                x, getYAxis().getDisplayPosition(aData.get(i).getYValue()),
                                x2,getYAxis().getDisplayPosition(aData.get(i+1).getYValue()),
                                x2,y4);
                        getPlotChildren().add(topPolygon);
                        topPolygon.toFront();
                        topPolygon.setFill(Color.RED);

                        // Color in the area below 2SD

                        double xb = getXAxis().getDisplayPosition(bData.get(i).getXValue());
                        double yb = getYAxis().getDisplayPosition(-10);
                        double xb2 = getXAxis().getDisplayPosition(bData.get(i+1).getXValue());
                        double yb2 = getYAxis().getDisplayPosition(-10);

                        Polygon bottomPolygon = new Polygon();

                        bottomPolygon.getPoints().addAll(xb,yb,
                                xb, getYAxis().getDisplayPosition(bData.get(i).getYValue()),
                                xb2,getYAxis().getDisplayPosition(bData.get((i+1)).getYValue()),
                                xb2,yb2
                        );
                        getPlotChildren().add(bottomPolygon);
                        bottomPolygon.toFront();
                        bottomPolygon.setFill(Color.GREEN);

                    }


                }
            };

    lineChart.setCreateSymbols(false);


    CategoryAxis xAxis2 = new CategoryAxis();
    xAxis2.setLabel("X");

    BarChart<String, Number> barChart = new BarChart<>(xAxis2, yAxis);
    barChart.setLegendVisible(false);
    barChart.setAnimated(false);
    //barChart.setAlternativeRowFillVisible(false);
    //barChart.setAlternativeColumnFillVisible(false);
    //barChart.setHorizontalGridLinesVisible(false);
    //barChart.setVerticalGridLinesVisible(false);
    barChart.getXAxis().setVisible(false);
    barChart.getYAxis().setVisible(false);

    XYChart.Series<String, Number> barSeries = new XYChart.Series<>();
    barSeries.getData().add(new XYChart.Data<>("1", 2.4));
    barSeries.getData().add(new XYChart.Data<>("2", 2.7));
    barSeries.getData().add(new XYChart.Data<>("3", 0.8));
    barSeries.getData().add(new XYChart.Data<>("4", -3.2));
    barSeries.getData().add(new XYChart.Data<>("5", -0.1));

    barChart.getData().addAll(barSeries);
    barChart.getStylesheets().add("sample/BarChart.css");
    barChart.setPadding(new Insets(0,0,35,3));

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

1 个答案:

答案 0 :(得分:0)

你可以让你的NumberAxis从0.5开始到5.5结束,然后刻度线几乎会重叠。然后,您告诉NumberAxisCategoryAxis不要显示它的刻度标记,这将是合适的。

如果您不想更改NumberAxis的范围,并且您可以将数字与BarChart的值对齐,则可以简单地告诉{{ 1}}不要显示它的刻度线。

该功能为CategoryAxis,您可能也应使用setTickLabelsVisible(boolean)

我没有测试过这个。