JavaFX 3-D 条形图与 Java 8

2024-01-15

是否有使用现代 3-D API 的最新 Java 8 的 3-D 条形图示例?

我想使用 Java 8 中的 3-D API。


JavaFX 的早期版本中有一个 3d-Bar-Chart 演示,但已被删除。

您可以自己创建条形图。只需创建一个网格和上面的一些框即可。这是对答案的轻微修改如何使用 JavaFX 创建 3D/曲面图表 https://stackoverflow.com/questions/31073007/how-to-create-a-3d-surface-chart-with-javafx/31125736#31125736。通过鼠标拖动,使用鼠标滚轮缩放。

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.PerspectiveCamera;
import javafx.scene.Scene;
import javafx.scene.SceneAntialiasing;
import javafx.scene.input.ScrollEvent;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.paint.Paint;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.Box;
import javafx.scene.shape.Line;
import javafx.scene.shape.Rectangle;
import javafx.scene.transform.Rotate;
import javafx.stage.Stage;

public class BarChart3dDemo extends Application {

    private static Random rnd = new Random();

    // size of graph
    int graphSize = 400;

    // variables for mouse interaction
    private double mousePosX, mousePosY;
    private double mouseOldX, mouseOldY;
    private final Rotate rotateX = new Rotate(20, Rotate.X_AXIS);
    private final Rotate rotateY = new Rotate(-45, Rotate.Y_AXIS);

    @Override
    public void start(Stage primaryStage) {

        // create axis walls
        Group grid = createGrid(graphSize);

        // initial cube rotation
        grid.getTransforms().addAll(rotateX, rotateY);

        // add objects to scene
        StackPane root = new StackPane();
        root.getChildren().add(grid);

        // create bars
        double gridSizeHalf = graphSize / 2;
        double size = 30;
        for (double i = -gridSizeHalf + size; i < gridSizeHalf; i += 50) {
            for (double j = -gridSizeHalf + size; j < gridSizeHalf; j += 50) {

                double height = rnd.nextDouble() * 300;

                Box box = new Box(size, height, size);

                // color
                PhongMaterial mat = new PhongMaterial();
                mat.setDiffuseColor(randomColor());
                box.setMaterial(mat);

                // location
                box.setLayoutY(-height * 0.5 + graphSize * 0.5);
                box.setTranslateX(i);
                box.setTranslateZ(j);

                grid.getChildren().addAll(box);

            }
        }

        // scene
        Scene scene = new Scene(root, 1600, 900, true, SceneAntialiasing.BALANCED);
        scene.setCamera(new PerspectiveCamera());

        scene.setOnMousePressed(me -> {
            mouseOldX = me.getSceneX();
            mouseOldY = me.getSceneY();
        });
        scene.setOnMouseDragged(me -> {
            mousePosX = me.getSceneX();
            mousePosY = me.getSceneY();
            rotateX.setAngle(rotateX.getAngle() - (mousePosY - mouseOldY));
            rotateY.setAngle(rotateY.getAngle() + (mousePosX - mouseOldX));
            mouseOldX = mousePosX;
            mouseOldY = mousePosY;

        });

        makeZoomable(root);

        primaryStage.setResizable(false);
        primaryStage.setScene(scene);
        primaryStage.show();

    }

    /**
     * Axis wall
     */
    public static class Axis extends Pane {

        Rectangle wall;

        public Axis(double size) {

            // wall
            // first the wall, then the lines => overlapping of lines over walls
            // works
            wall = new Rectangle(size, size);
            getChildren().add(wall);

            // grid
            double zTranslate = 0;
            double lineWidth = 1.0;
            Color gridColor = Color.WHITE;

            for (int y = 0; y <= size; y += size / 10) {

                Line line = new Line(0, 0, size, 0);
                line.setStroke(gridColor);
                line.setFill(gridColor);
                line.setTranslateY(y);
                line.setTranslateZ(zTranslate);
                line.setStrokeWidth(lineWidth);

                getChildren().addAll(line);

            }

            for (int x = 0; x <= size; x += size / 10) {

                Line line = new Line(0, 0, 0, size);
                line.setStroke(gridColor);
                line.setFill(gridColor);
                line.setTranslateX(x);
                line.setTranslateZ(zTranslate);
                line.setStrokeWidth(lineWidth);

                getChildren().addAll(line);

            }

        }

        public void setFill(Paint paint) {
            wall.setFill(paint);
        }

    }

    public void makeZoomable(StackPane control) {

        final double MAX_SCALE = 20.0;
        final double MIN_SCALE = 0.1;

        control.addEventFilter(ScrollEvent.ANY, new EventHandler<ScrollEvent>() {

            @Override
            public void handle(ScrollEvent event) {

                double delta = 1.2;

                double scale = control.getScaleX();

                if (event.getDeltaY() < 0) {
                    scale /= delta;
                } else {
                    scale *= delta;
                }

                scale = clamp(scale, MIN_SCALE, MAX_SCALE);

                control.setScaleX(scale);
                control.setScaleY(scale);

                event.consume();

            }

        });

    }

    /**
     * Create axis walls
     *
     * @param size
     * @return
     */
    private Group createGrid(int size) {

        Group cube = new Group();

        // size of the cube
        Color color = Color.LIGHTGRAY;

        List<Axis> cubeFaces = new ArrayList<>();
        Axis r;

        // back face
        r = new Axis(size);
        r.setFill(color.deriveColor(0.0, 1.0, (1 - 0.5 * 1), 1.0));
        r.setTranslateX(-0.5 * size);
        r.setTranslateY(-0.5 * size);
        r.setTranslateZ(0.5 * size);

        cubeFaces.add(r);

        // bottom face
        r = new Axis(size);
        r.setFill(color.deriveColor(0.0, 1.0, (1 - 0.4 * 1), 1.0));
        r.setTranslateX(-0.5 * size);
        r.setTranslateY(0);
        r.setRotationAxis(Rotate.X_AXIS);
        r.setRotate(90);

        cubeFaces.add(r);

        // right face
        r = new Axis(size);
        r.setFill(color.deriveColor(0.0, 1.0, (1 - 0.3 * 1), 1.0));
        r.setTranslateX(-1 * size);
        r.setTranslateY(-0.5 * size);
        r.setRotationAxis(Rotate.Y_AXIS);
        r.setRotate(90);

        // cubeFaces.add( r);

        // left face
        r = new Axis(size);
        r.setFill(color.deriveColor(0.0, 1.0, (1 - 0.2 * 1), 1.0));
        r.setTranslateX(0);
        r.setTranslateY(-0.5 * size);
        r.setRotationAxis(Rotate.Y_AXIS);
        r.setRotate(90);

        cubeFaces.add(r);

        // top face
        r = new Axis(size);
        r.setFill(color.deriveColor(0.0, 1.0, (1 - 0.1 * 1), 1.0));
        r.setTranslateX(-0.5 * size);
        r.setTranslateY(-1 * size);
        r.setRotationAxis(Rotate.X_AXIS);
        r.setRotate(90);

        // cubeFaces.add( r);

        // front face
        r = new Axis(size);
        r.setFill(color.deriveColor(0.0, 1.0, (1 - 0.1 * 1), 1.0));
        r.setTranslateX(-0.5 * size);
        r.setTranslateY(-0.5 * size);
        r.setTranslateZ(-0.5 * size);

        // cubeFaces.add( r);

        cube.getChildren().addAll(cubeFaces);

        return cube;
    }

    public static double normalizeValue(double value, double min, double max, double newMin, double newMax) {

        return (value - min) * (newMax - newMin) / (max - min) + newMin;

    }

    public static double clamp(double value, double min, double max) {

        if (Double.compare(value, min) < 0)
            return min;

        if (Double.compare(value, max) > 0)
            return max;

        return value;
    }

    public static Color randomColor() {
        return Color.rgb(rnd.nextInt(255), rnd.nextInt(255), rnd.nextInt(255));
    }

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

}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JavaFX 3-D 条形图与 Java 8 的相关文章

  • 如何在javafx中获取当前屏幕详细信息?

    我的电脑连接了多个显示器 从 javaFX 我可以获得主屏幕 但我需要了解当前舞台所在屏幕的屏幕详细信息 我怎样才能得到它 尝试使用获取矩形屏幕 http docs oracle com javafx 2 api javafx stage
  • 如何使用 javafx 创建响应式文本?

    我创建了一个标签 其中显示了一个数字 现在我想让这个数字响应 GUI 我怎样才能做到这一点 这是我的号码及其当前字体大小 Label label new Label label setText 12 label setFont Font f
  • 在 Jar 中为 Gluon Scene Builder 11.00 创建自定义控件

    我想在可执行 jar 文件中创建自定义控件 然后在 Gluon Scene Builder 11 00 中使用 我需要知道如何做到这一点 我尝试了几种形式 但在场景生成器中导入 jar 时我的控件没有出现 我正在使用 IntelliJ Co
  • 无法解析符号“javafx.scene.web”

    使用Intellij 2021 3 2 JavaFX版本 11 0 2 1 我正在尝试将 JavaFX WebView 添加到我的应用程序中 我的导入语句无法编译 import javafx scene web 编译错误 java 找不到符
  • JavaFX 如何在不改变线宽的情况下缩放路径的坐标?

    我目前正在制作具有缩放和平移功能的阶梯折线图 由于我需要处理的数据量非常大 因此每次调用layoutPlotChildren 时 我无法重新创建步骤线的整个路径 所以我的想法是创建一次路径元素 然后在缩放和平移事件时对其进行转换 到目前为止
  • 确定 JavaFX 中是否消耗了事件

    我正在尝试使用 JavaFX 中的事件处理来做一些非滑雪道的事情 我需要能够确定手动触发事件后是否已消耗该事件 在以下示例中 正确接收了合成鼠标事件 但调用 Consumer 不会更新该事件 我对此进行了调试 发现 JavaFX 实际上创建
  • 将 JavaFX FXML 对象分组在一起

    非常具有描述性和信息性的答案将从我这里获得价值 50 声望的赏金 我正在 JavaFX 中开发一个应用程序 对于视图 我使用 FXML
  • JavaFX:将像素写入 PixelWriter 的最快方法

    我正在寻找最快的方式来写入像素javafx scene image Image 写信给BufferedImage的后备数组要快得多 至少在我制作的测试图像上 只花了大约 20 毫秒BufferedImage WritableImage另一方
  • Javafx 组合框不会在实时更改时更新下拉列表大小?

    我正在使用 Javafx v8 0 25 b18 我出现的问题是动态组合框的下拉列表的大小不会改变 所以如果我最初在下拉列表中有两个项目 那么下拉列表大小将适合两个项目 但如果我现在用以下内容填充动态组合框三个项目 然后我在里面得到一个小滚
  • javafx组合框下拉菜单从屏幕边缘跳出

    我有最新版本的 java 8 40 和 javaFX 我有一个包含 10 个项目的复选框 我编译并运行该程序 如果我将程序窗口移至监视器屏幕的底部 下拉列表将从监视器屏幕中消失 无法将项目点击出屏幕 相反 如果我尝试使用场景生成器 2 0
  • 在 JavaFX 中拖动未装饰的舞台

    我希望将舞台设置为 未装饰 使其可拖动且可最小化 问题是我找不到这样做的方法 因为我遇到的示例是通过插入到主方法中的方法来实现的 我想通过控制器类中声明的方法来完成此操作 就像我如何使用下面的 WindowClose 方法来完成此操作 这是
  • 包含 ListView 更新、CellValueFactory 的 JavaFX TableView

    我确实有一个引擎 其中包含以下列表中的部件 UPDATE 我更新了文本以提供示例 我想要一个包含 2 列 名称 零件 的引擎 TableView 我希望将 Column 部分呈现为 TableCell 中的 ListView 因此我重写了该
  • Gluon 移动 iOS 音频播放器

    由于 JavaFx Media 尚未移植到移动平台 任何人都可以帮助我使用本机 iOS APi 来播放声音 mp3 文件 该文件将存储在我的 gluon 项目的 main resources 文件夹中 在 Android 上 我们可以轻松地
  • 复选框选择与 TableView 绑定

    How to bind with TableView selection model with checkbox isSelected in table view In manually using mouse multiple selec
  • mobileapplication.mobileevent BACK_BUTTON_PRESSED

    我的两个视图中有 2 个 Android 本机音频实例 当用户按下后退按钮并离开视图时 我试图让音频停止 因为它不会自动发生 我查看了文档并看到了 MobileEvent 类 我尝试实现它的构造函数 但没有成功 这是我的第一个应用程序 为此
  • FXML 文件中的 getHostServices().showDocument()

    有没有简单的方法可以将 getHostServices showDocument 命令放入 toHomepage 方法中 而不是执行一行又一行的代码 这样代码应该看起来干净简单 package sample import javafx ap
  • 使用 Maven 构建 JavaFX 8

    我测试了使用 Netbeans 7 4 创建 JavaFX 8 项目 但不幸的是没有运气 这是 POM 文件
  • 如何获取JavaFX的版本号?

    如何在运行时找出我正在使用哪个版本的 JavaFX 简单的方法之一就是简单地阅读javafx properties文件位于您的 JAVA HOME jre lib目录 我现在安装了 Java 1 7 u9 与之捆绑的 JavaFX 是 v2
  • JavaFX - setVisible 隐藏元素但不重新排列相邻节点

    在 JavaFX 中 如果我有一个场景有 2VBox元素和每个VBox有多个Label in it 如果我设置顶部VBox to 无形的 为什么底部VBox 不向上移动顶部的场景VBox was The VBox is 无形的但我希望其他物
  • 在JavaFX中如何在表视图中添加带有数据的组合框

    我已经尝试了很多 但无法将数据库中的所有值填充到我的组合框表格单元格中 控制器 java public class controller GetConnection gc new GetConnection PreparedStatemen

随机推荐