JavaFX图表未正确分层 重叠图例将图例移近轴

我正在构建一个Java桌面应用程序,需要为其生成图表。其中之一需要是条形图,上面有一个折线图。

我使用StackPane覆盖了两个图形,并分别填充了它们,但是正如您在图片中看到的那样,它们没有正确覆盖,折线图从y轴的左侧开始。同样,当左y轴没有标签(???)时,这种情况也会改变,从某种意义上说,这条线显示正确,但条形被弄乱了。

每个图表我也有两个不同的Y轴,但是右边的那个并没有显示。

我怎样才能使所有内容都很好地重叠并且正确定位每个图形?我在做什么错了?

输出:

JavaFX图表未正确分层
      
    重叠图例将图例移近轴

public class Graphs implements Initializable {

@FXML StackPane stackPane;
@FXML BarChart barChart;
@FXML CategoryAxis xAxis;
@FXML NumberAxis yAxis;
@FXML NumberAxis yAxisRight;
@FXML LineChart lineChartEffective;

@Override
public void initialize(URL url,ResourceBundle resourceBundle) {


    xAxis.setCategories(FXCollections.<String>observableArrayList("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"));


    yAxis.setLowerBound(0);
    yAxis.setUpperBound(100);
    yAxis.setTickUnit(10);


     yAxisRight.setSide(Side.RIGHT);
     yAxisRight.setLowerBound(0);
     yAxisRight.setUpperBound(50);
     yAxisRight.setTickUnit(1);


     barChart.setLegendVisible(false);
     barChart.setanimated(false);

     barChart.setLegendVisible(false);
     barChart.setanimated(false);

     barChart.setalternativeRowFillVisible(false);
     barChart.setalternativeColumnFillVisible(false);
     barChart.setHorizontalGridLinesVisible(false);
     barChart.setVerticalGridLinesVisible(false);
     barChart.getXAxis().setVisible(true);
     barChart.getYAxis().setVisible(true);


    barChart.getData().add(getaverageloadPerFTE());

    xAxis.setLabel("Month");
    yAxis.setLabel("Level (%)");
    yAxisRight.setLabel("Level (u)");


    lineChartEffective.setLegendVisible(false);
    lineChartEffective.setanimated(false);
    lineChartEffective.setCreateSymbols(true);
    lineChartEffective.setalternativeRowFillVisible(false);
    lineChartEffective.setalternativeColumnFillVisible(false);
    lineChartEffective.setHorizontalGridLinesVisible(false);
    lineChartEffective.setVerticalGridLinesVisible(false);
    lineChartEffective.getXAxis().setVisible(false);
    lineChartEffective.getYAxis().setVisible(true);
    lineChartEffective.getStylesheets().addAll(getclass().getResource("chartEffective.css").toExternalForm());
    lineChartEffective.getData().add( getEffectiveCustomerSupport());



}

private XYChart.Series<String,Number> getaverageloadPerFTE() {
    XYChart.Series<String,Number> series = new XYChart.Series<String,Number>();
    series.getData().add(new XYChart.Data<String,Number>("Jan",58 ));
    series.getData().add(new XYChart.Data<String,Number>("Feb",54 ));
    series.getData().add(new XYChart.Data<String,Number>("Mar",47 ));
    series.getData().add(new XYChart.Data<String,Number>("Apr",34 ));
    series.getData().add(new XYChart.Data<String,Number>("May",33 ));
    series.getData().add(new XYChart.Data<String,Number>("Jun",32 ));
    series.getData().add(new XYChart.Data<String,Number>("Jul",30 ));
    series.getData().add(new XYChart.Data<String,Number>("Aug",36 ));
    series.getData().add(new XYChart.Data<String,Number>("Sep",29 ));
    series.getData().add(new XYChart.Data<String,Number>("Oct",Number>("Nov",0 ));
    series.getData().add(new XYChart.Data<String,Number>("Dec",0 ));



    series.setName("Average load per FTE");

    return series;
}

private XYChart.Series<String,Number> getEffectiveCustomerSupport() {
        XYChart.Series<String,Number>();
        series.getData().add(new XYChart.Data<String,2.9 ));
        series.getData().add(new XYChart.Data<String,2.7 ));
        series.getData().add(new XYChart.Data<String,3.3 ));
        series.getData().add(new XYChart.Data<String,3.4 ));
        series.getData().add(new XYChart.Data<String,3.2 ));
        series.getData().add(new XYChart.Data<String,4 ));
        series.getData().add(new XYChart.Data<String,3.8 ));
        series.getData().add(new XYChart.Data<String,4.1 ));
        series.getData().add(new XYChart.Data<String,0 ));
        series.getData().add(new XYChart.Data<String,0 ));


        series.setName("Effective customer support");

        return series;
    }


}

Graphs.fxml:

 <?xml version="1.0" encoding="UTF-8"?>

    <?import javafx.scene.layout.*?>

    <?import javafx.scene.chart.LineChart?>
    <?import javafx.scene.chart.CategoryAxis?>
    <?import javafx.scene.chart.NumberAxis?>
    <?import javafx.scene.chart.BarChart?>
    <AnchorPane prefHeight="731.0" prefWidth="878.0" xmlns="http://javafx.com/javafx/10.0.2-internal" xmlns:fx="http://javafx.com/fxml/1" fx:controller="Graphs">
       <children>

          <StackPane fx:id="stackPane" layoutX="26.0" layoutY="32.0" prefHeight="523.0" prefWidth="708.0">
             <children>
                <BarChart fx:id="barChart" >
                  <xAxis>
                    <CategoryAxis side="BOTTOM" />
                  </xAxis>
                  <yAxis>
                    <NumberAxis fx:id = "yAxis" side="LEFT" />
                  </yAxis>
                </BarChart>

                 <LineChart fx:id="lineChartEffective"  stylesheets="@chartEffective.css">
                     <xAxis>
                         <CategoryAxis fx:id = "xAxis" side="BOTTOM" />
                     </xAxis>
                     <yAxis>
                         <NumberAxis fx:id="yAxisRight" side="RIGHT"/>
                     </yAxis>
                 </LineChart>

             </children>
          </StackPane>

       </children>
    </AnchorPane>

chartsEffective.css:

      .chart-plot-background {
        -fx-background-color: transparent;
        }
        .default-color0.chart-series-line {
        -fx-stroke: #4b0082;
        }
        .default-color0.chart-line-symbol {
            -fx-background-color: #4b0082,white;
        }
lienzhangyubo 回答:JavaFX图表未正确分层 重叠图例将图例移近轴

绘图区域对齐

您可以使用 HBoxPane 填充符来抵消图表之间的宽度差异。这也可以通过 translateXStackPane 对齐选项来完成,但是当您动态最小化/最大化/调整窗口大小时,这些解决方案可能会出现故障。

private static <X,Y> HBox wrapChart(XYChart<X,Y> chart1,XYChart<X,Y> chart2,boolean left)
{
    Pane filler = new Pane();
    filler.minWidthProperty().bind(chart2.getYAxis().widthProperty());
    filler.maxWidthProperty().bind(chart2.getYAxis().widthProperty());
    HBox.setHgrow(chart1,Priority.ALWAYS);
    return left ? new HBox(chart1,filler) : new HBox(filler,chart1);
}

stackPane.getChildren().addAll
(
    wrapChart(leftChart,rightChart,true),wrapChart(rightChart,leftChart,false)
)

次要元素对齐

但它还有更多问题。当您更改轴 side 属性时,标题和图例位置也将更改。您需要决定如何处理这些问题。您可以删除冲突的元素或将它们完美对齐。

以下部分描述了如何将次要元素与默认边 (BOTTOM) 对齐。这也适用于 TOP 端。

标题对齐

for(Node n : leftChart.lookupAll(".chart-title"))
    n.translateXProperty().bind(rightChart.getYAxis().widthProperty().divide(2));
for(Node n : rightChart.lookupAll(".chart-title"))
    n.translateXProperty().bind(leftChart.getYAxis().widthProperty().multiply(-1).divide(2));

图例对齐

重叠图例

如果图例相同,那么您可以将它们重叠或隐藏其中之一。

for(Node n : leftChart.lookupAll(".chart-legend"))
    n.translateXProperty().bind(rightChart.getYAxis().widthProperty().divide(2));
for(Node n : rightChart.lookupAll(".chart-legend"))
    n.translateXProperty().bind(leftChart.getYAxis().widthProperty().divide(2).multiply(-1));

将图例移近轴

如果图例不同,那么您可以将它们移近它们的轴

for(Node n : leftChart.lookupAll(".chart-legend"))
    n.translateXProperty().bind(n.layoutXProperty().divide(2).multiply(-1));
for(Node n : rightChart.lookupAll(".chart-legend"))
    n.translateXProperty().bind(n.layoutXProperty().divide(2));

杂项

您还可以使用包含上述所有代码及更多内容的 DoubleXYChart

本文链接:https://www.f2er.com/3007016.html

大家都在问