如何动态更改JavaFX图表中的符号/点大小?

时间:2019-01-12 15:25:54

标签: css javafx fxml linechart

我知道可以创建这样的CSS文件并将其设置在我的场景中。

.chart-line-symbol { -fx-scale-x: 0.5; -fx-scale-y: 0.5; }

但这不是我所需要的。如果执行此操作,则点大小将始终相同。

如何使用从TextField获得的值动态地更改图表符号的大小?

ChangeSymbolSize.java

package changesymbolsize;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class ChangeSymbolSize extends Application {

    @Override
    public void start(Stage stage) throws Exception {
        Parent root = FXMLLoader.load(getClass().getResource("MainLayout.fxml"));

        Scene scene = new Scene(root);

        stage.setTitle("Changing the symbol size");
        stage.setScene(scene);
        stage.show();
    }

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

}

MainLayout.fxml

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

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.SplitPane?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.FlowPane?>

<AnchorPane id="AnchorPane" prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/10.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="changesymbolsize.MainLayoutController">
   <children>
      <SplitPane dividerPositions="0.25" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
        <items>
          <AnchorPane>
               <children>
                  <TextField fx:id="txt_pointSize" layoutX="14.0" layoutY="31.0" onAction="#setPointSize" prefWidth="60.0" AnchorPane.leftAnchor="14.0" AnchorPane.topAnchor="31.0" />
                  <Label layoutX="14.0" layoutY="14.0" text="Point Size" AnchorPane.leftAnchor="14.0" AnchorPane.topAnchor="14.0" />
                  <Button layoutX="74.0" layoutY="31.0" mnemonicParsing="false" onAction="#setPointSize" text="OK" />
               </children>
            </AnchorPane>
            <FlowPane fx:id="pane_chart" />
        </items>
      </SplitPane>
   </children>
</AnchorPane>

MainLayoutController.java

package changesymbolsize;

import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.FlowPane;

public class MainLayoutController implements Initializable {

    @FXML
    private Label label;

    @FXML
    private TextField txt_pointSize;

    @FXML
    private FlowPane pane_chart;

    LineChart<Number, Number> lineChart;

    @FXML
    private void setPointSize(ActionEvent event) {
        System.out.println("We should be able to change the symbol size");
        System.out.println("using the value from the TextField");
        double size = Double.parseDouble(txt_pointSize.getText());
        // But how?

    }

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        pane_chart.getChildren().add(getExampleChart());
    }

    Node getExampleChart(){
        NumberAxis xAxis = new NumberAxis();
        NumberAxis yAxis = new NumberAxis();

        lineChart = new LineChart<Number, Number>(xAxis, yAxis);

        int a = 6;
        int b = 2;
        lineChart.setTitle("f(x) = " + a + " x + " + b);

        XYChart.Series series = new XYChart.Series();
        series.setName("Example 1");

        for (int x = 0; x <= 100; x++) {
            double y = (a * x) + b;
            series.getData().add(new XYChart.Data(x, y));
        }
        lineChart.getData().add(series);
        lineChart.setCreateSymbols(true);

        return lineChart;
    }
}

我是JavaFX和CSS的新手。所以我不知道我想做的事是否容易,但是我在弄清楚如何做到这一点时遇到了麻烦。

1 个答案:

答案 0 :(得分:0)

您可以使用

获取Nodes
for (XYChart.Series < Number, Number > series: lineChart.getData()) {
 //for all series, take date, each data has Node (symbol) for representing point
 for (XYChart.Data < Number, Number > data: series.getData()) {
  Node node = data.getNode();
  node.setScaleX(Double.parseDouble(newValue));
  node.setScaleY(Double.parseDouble(newValue));
 }
}
  

完整代码:

import javafx.application.Application;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.ScatterChart;
import javafx.scene.chart.XYChart;
import javafx.scene.control.TextField;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
/**
 *
 * @author Sedrick
 */
public class Chart extends Application {

 @Override
 public void start(Stage stage) {

  //set Axis
  final NumberAxis xAxis = new NumberAxis();
  final NumberAxis yAxis = new NumberAxis();

  //chart
  final ScatterChart < Number, Number > lineChart = new ScatterChart(xAxis, yAxis);

  //prepare series
  XYChart.Series series1 = new XYChart.Series();
  series1.getData().add(new XYChart.Data(1, 2));
  series1.getData().add(new XYChart.Data(2, 2));
  series1.getData().add(new XYChart.Data(3, 1));
  series1.getData().add(new XYChart.Data(3, 3));
  series1.getData().add(new XYChart.Data(5, 2));

  HBox hbox = new HBox();
  //add series to chart
  lineChart.getData().addAll(series1);




  TextField textField = new TextField();
  textField.textProperty().addListener((observable, oldValue, newValue) -> {
   if (newValue.matches("[0-9]*")) {
    //take all series
    for (XYChart.Series < Number, Number > series: lineChart.getData()) {
     //for all series, take date, each data has Node (symbol) for representing point
     for (XYChart.Data < Number, Number > data: series.getData()) {          
      Node node = data.getNode();
      node.setScaleX(Double.parseDouble(newValue));
      node.setScaleY(Double.parseDouble(newValue));
     }
    }
   }

  });

  hbox.getChildren().addAll(lineChart, textField);
  Scene scene = new Scene(hbox, 800, 600);
  //scene.getStylesheets().add(getClass().getResource("/resources/chart.css").toExternalForm());
  stage.setScene(scene);
  stage.show();
 }

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