Диаграммы в пакете javafx.scene.chart
не используют Canvas
для рисования диаграмм. Вместо этого они используют граф сцены. В своем вопросе вы создаете изображение на лету, но, если у вас уже есть созданное изображение, возможно, как встроенный ресурс, вы можете использовать CSS, чтобы добавить изображение к фону диаграммы. Взглянув на раздел XYChart
JavaFX CSS Справочное руководство , вы увидите, что одна из подструктур помечена chart-plot-background
и является Region
, что означает, что фоновое изображение можно применить к это через CSS. Например:
Приложение. java:
import java.util.Random;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart.Data;
import javafx.scene.chart.XYChart.Series;
import javafx.stage.Stage;
public class App extends Application {
@Override
public void start(Stage primaryStage) {
var chart = new LineChart<>(new NumberAxis(), new NumberAxis(), createChartData());
chart.getXAxis().setLabel("X");
chart.getYAxis().setLabel("Y");
var scene = new Scene(chart, 1000, 650);
scene.getStylesheets().add(getClass().getResource("/style.css").toString());
primaryStage.setScene(scene);
primaryStage.show();
}
private static ObservableList<Series<Number, Number>> createChartData() {
var random = new Random();
var chartData = FXCollections.<Series<Number, Number>>observableArrayList();
for (int i = 1; i <= 3; i++) {
var data = FXCollections.<Data<Number, Number>>observableArrayList();
for (int j = 0; j <= 15; j++) {
data.add(new Data<>(j, random.nextInt(250)));
}
chartData.add(new Series<>("Series #" + i, data));
}
return chartData;
}
}
стиль. css:
.chart-plot-background {
-fx-background-image: url(/* your URL */);
-fx-background-size: cover;
}
Это только нарисует изображение позади фактического содержимого диаграммы (то есть данных). На оси, легенде и окружающем пространстве не будет изображения. Если вы хотите, чтобы вся диаграмма имела фоновое изображение, вы можете использовать тот факт, что Chart
, от которого наследуются все реализации диаграммы, начинается с Region
. Измените CSS на:
.chart {
-fx-background-image: url(/* your URL */);
-fx-background-size: cover;
}
.chart-plot-background,
.chart-legend {
-fx-background-color: null;
}
Если вы хотите что-то между фоном графика и всей диаграммой, вы можете добавить изображение к .chart-content
(задокументировано здесь ).
Если вам нужно оставаться в коде (например, потому что вы создаете изображение на лету), вам нужно получить ссылку на необходимый Region
. Для этого вы можете использовать Node#lookup(String)
. Имейте в виду, однако, что вам может потребоваться подождать, пока диаграмма не будет отображена на экране, прежде чем вызывать lookup
, поскольку возможно, что нужный узел-потомок не был создан и добавлен в граф сцены заранее (это особенно верно для элементов управления ).
import java.util.Random;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart.Data;
import javafx.scene.chart.XYChart.Series;
import javafx.scene.image.Image;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundImage;
import javafx.scene.layout.BackgroundPosition;
import javafx.scene.layout.BackgroundSize;
import javafx.scene.layout.Region;
import javafx.stage.Stage;
public class App extends Application {
@Override
public void start(Stage primaryStage) {
var chart = new LineChart<>(new NumberAxis(), new NumberAxis(), createChartData());
chart.setTitle("Example Chart");
chart.getXAxis().setLabel("X");
chart.getYAxis().setLabel("Y");
var scene = new Scene(chart, 1000, 650);
primaryStage.setScene(scene);
primaryStage.show();
var plotBackground = (Region) chart.lookup(".chart-plot-background");
plotBackground.setBackground(
new Background(
new BackgroundImage(
new Image(/* your URL */),
null,
null,
BackgroundPosition.CENTER,
new BackgroundSize(0, 0, false, false, true, false))));
}
private static ObservableList<Series<Number, Number>> createChartData() {
var random = new Random();
var chartData = FXCollections.<Series<Number, Number>>observableArrayList();
for (int i = 1; i <= 3; i++) {
var data = FXCollections.<Data<Number, Number>>observableArrayList();
for (int j = 0; j <= 15; j++) {
data.add(new Data<>(j, random.nextInt(250)));
}
chartData.add(new Series<>("Series #" + i, data));
}
return chartData;
}
}
Обратите внимание, что вы не можете использовать BufferedImage
напрямую с API JavaFX. Если вам действительно нужно нарисовать код Image
, у вас есть несколько вариантов: