【问题标题】:JavaFX 3-D Bar chart with Java 8带有 Java 8 的 JavaFX 3-D 条形图
【发布时间】:2014-04-01 10:29:21
【问题描述】:

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

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

【问题讨论】:

    标签: javafx javafx-2 javafx-8


    【解决方案1】:

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

    您可以自己创建条形图。只需在其上创建一个网格和一些框。这里对How to create a 3d / surface chart with JavaFX 中的答案稍作修改。通过鼠标拖动,使用鼠标滚轮进行缩放。

    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);
        }
    
    }
    

    【讨论】:

    • 这是一个条形图示例。您所要做的就是为其添加刻度线。
    • 这对我来说太高级了。
    【解决方案2】:

    参考这个例子,如果对你有帮助的话,它显示了 3-D 条形图的使用。 http://www.jroller.com/dgilbert/entry/creating_3d_charts_in_java

    【讨论】:

    • 看起来不错,但我没有在其中看到 JavaFX。我需要 JavaFX 的示例。
    • 你是对的,链接示例中没有 JavaFX(Orson Charts 库使用纯 Java2D 进行渲染)。
    【解决方案3】:

    Jzy3d 在其gallery 中有漂亮的条形图。您可以轻松地将 Jzy3d 与 JavaFX 一起使用。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-05-22
    • 2016-08-08
    • 1970-01-01
    • 1970-01-01
    • 2016-05-16
    • 1970-01-01
    • 2018-06-03
    • 1970-01-01
    相关资源
    最近更新 更多