Intereting Posts
Ошибка в настройке области с помощью kotlin Элементы меню панели инструментов Android никогда не отображаются, но переходят в переполнение Напишите большой входной поток в файл в Котлине В TornadoFX, как я могу привязать свойства BigDecimal к другому свойству BigDecimal с помощью objectBinding? Файл kotlin не поддерживает блок-схему, написанную markdown? Конфигурация проекта котла в Gradle с помощью Gradle Script Kotlin Есть ли способ легко открыть и закрыть поток в котлин? Как решить эту «нерешенную ссылку», когда я определил эту функцию? Отражение Котлина: параметр неизвестного типа Отправка SMS с помощью Twilio и Android Kotlin VS Scala: реализовать методы с параметрами первичного конструктора Android Kotlin: Смысл бесплатной функции с использованием Mockito / PowerMock Весенние данные mongodb и kotlin TornadoFX Как создать MDI со списком моделей дочерних окон? Чем отличаются код A и код B в Котлине?

Как смешивать ScatterChart с горизонтальными и вертикальными линиями

Я пытаюсь создать вертикальные и горизонтальные линии на ScatterChart вместе с точками. Я не могу найти способ их смешать.

введите описание изображения здесь

Это код, который я генерирую на диаграмме.

vbox { add(ScatterChart(NumberAxis(), NumberAxis()).apply { val seriesMap: HashMap<String, XYChart.Series<Number, Number>> = HashMap() pointsList .map { it.decisionClass } .distinct() .forEach { seriesMap.put(it, XYChart.Series()) } for (point in pointsList) { seriesMap.get(point.decisionClass)?.data(point.axisesValues[0], point.axisesValues[1]) } seriesMap .toSortedMap() .forEach { key, value -> value.name = key data.add(value) } (xAxis as NumberAxis).setForceZeroInRange(false) (yAxis as NumberAxis).setForceZeroInRange(false) }) } 

Я не знаю Котлина, поэтому этот ответ на Java. Я думаю, вы можете перевести его в Котлин (и не стесняйтесь публиковать другой ответ, если это так).

Чтобы добавить дополнительные узлы в диаграмму, необходимо три вещи:

  1. Вызовите getPlotChildren() и добавьте новые узлы в «графические дети» графика,
  2. Переопределите метод layoutPlotChildren() чтобы обновить позиции ваших узлов при layoutPlotChildren() графика
  3. Используйте getDisplayPosition(...) , определенный в Axis , чтобы получить местоположение в системе координат области графика диаграммы от значения на оси.

Следующий SSCCE создает диаграмму рассеяния, несколько похожую на ту, которую вы опубликовали на снимке экрана, и добавляет строки, стробирующие указанную серию (то есть линия слева увеличивает высоту диаграммы и проходит через минимальное значение x серии , линия наверху расширяет ширину диаграммы и проходит через максимальное значение y ряда и т. д.). Я добавил радиокнопки, чтобы вы могли выбрать, какая серия «ограничена» линиями.

 import java.util.Random; import javafx.application.Application; import javafx.collections.FXCollections; import javafx.scene.Scene; import javafx.scene.chart.NumberAxis; import javafx.scene.chart.ScatterChart; import javafx.scene.chart.XYChart.Data; import javafx.scene.chart.XYChart.Series; import javafx.scene.control.RadioButton; import javafx.scene.control.ToggleGroup; import javafx.scene.layout.BorderPane; import javafx.scene.layout.VBox; import javafx.scene.shape.Line; import javafx.stage.Stage; public class ScatterChartWithLines extends Application { private final class ScatterChartWithBoundary extends ScatterChart<Number, Number> { private Series<Number, Number> boundedSeries ; private final NumberAxis yAxis; private final NumberAxis xAxis; private final Line leftLine = new Line(); private final Line rightLine = new Line(); private final Line topLine = new Line(); private final Line bottomLine = new Line(); { getPlotChildren().addAll(leftLine, rightLine, topLine, bottomLine); } private ScatterChartWithBoundary(NumberAxis xAxis, NumberAxis yAxis) { super(xAxis, yAxis); this.yAxis = yAxis; this.xAxis = xAxis; } @Override protected void layoutPlotChildren() { super.layoutPlotChildren(); getPlotChildren().removeAll(leftLine, rightLine, topLine, bottomLine); if (boundedSeries != null) { getPlotChildren().addAll(leftLine, rightLine, topLine, bottomLine); double minX = Double.MAX_VALUE ; double minY = Double.MAX_VALUE ; double maxX = Double.MIN_VALUE ; double maxY = Double.MIN_VALUE ; for (Data<Number, Number> d : boundedSeries.getData()) { if (d.getXValue().doubleValue() < minX) minX = d.getXValue().doubleValue() ; if (d.getXValue().doubleValue() > maxX) maxX = d.getXValue().doubleValue() ; if (d.getYValue().doubleValue() < minY) minY = d.getYValue().doubleValue() ; if (d.getYValue().doubleValue() > maxY) maxY = d.getYValue().doubleValue() ; } positionLineInAxisCoordinates(leftLine, minX, yAxis.getLowerBound(), minX, yAxis.getUpperBound()); positionLineInAxisCoordinates(rightLine, maxX, yAxis.getLowerBound(), maxX, yAxis.getUpperBound()); positionLineInAxisCoordinates(bottomLine, xAxis.getLowerBound(), minY, xAxis.getUpperBound(), minY); positionLineInAxisCoordinates(topLine, xAxis.getLowerBound(), maxY, xAxis.getUpperBound(), maxY); } } private void positionLineInAxisCoordinates(Line line, double startX, double startY, double endX, double endY) { double x0 = xAxis.getDisplayPosition(startX); double x1 = xAxis.getDisplayPosition(endX); double y0 = yAxis.getDisplayPosition(startY); double y1 = yAxis.getDisplayPosition(endY); line.setStartX(x0); line.setStartY(y0); line.setEndX(x1); line.setEndY(y1); } public void setBoundedSeries(Series<Number, Number> boundedSeries) { if (! getData().contains(boundedSeries)) { throw new IllegalArgumentException("Specified series is not displayed in this chart"); } this.boundedSeries = boundedSeries ; requestChartLayout(); } } private final Random rng = new Random(); @Override public void start(Stage primaryStage) { Series<Number, Number> series1 = new Series<>("Series 1", FXCollections.observableArrayList()); Series<Number, Number> series2 = new Series<>("Series 2", FXCollections.observableArrayList()); Series<Number, Number> series3 = new Series<>("Series 3", FXCollections.observableArrayList()); for (int i = 0 ; i < 40 ; i++) { series1.getData().add(new Data<>(rng.nextDouble()*2 + 4, rng.nextDouble()*3 + 2)); series2.getData().add(new Data<>(rng.nextDouble()*2.5 + 4.75, rng.nextDouble()*1.5 + 2)); series3.getData().add(new Data<>(rng.nextDouble()*3 + 5, rng.nextDouble()*1.5 + 2.75)); } NumberAxis xAxis = new NumberAxis(); NumberAxis yAxis = new NumberAxis(); xAxis.setForceZeroInRange(false); yAxis.setForceZeroInRange(false); ScatterChartWithBoundary chart = new ScatterChartWithBoundary(xAxis, yAxis); chart.getData().addAll(series1, series2, series3); VBox buttons = new VBox(2); ToggleGroup toggleGroup = new ToggleGroup(); for (Series<Number, Number> series : chart.getData()) { RadioButton rb = new RadioButton(series.getName()); rb.selectedProperty().addListener((obs, wasSelected, isNowSelected) -> { if (isNowSelected) { chart.setBoundedSeries(series); } }); rb.setToggleGroup(toggleGroup); buttons.getChildren().add(rb); } BorderPane root = new BorderPane(chart); root.setTop(buttons); Scene scene = new Scene(root); primaryStage.setScene(scene); primaryStage.show(); } public static void main(String[] args) { launch(args); } } 

Вот типичный результат:

введите описание изображения здесь