Skip to content
jzy3dPublic

About

A Java API for 3d and 2d charts

Topics

Resources

Stars

309 stars

Watchers

22 watching

Forks

Repository files navigation

Jzy3d

Jzy3d is a framework for easily drawing 3d and 2d charts in Java, using either fast native GPU rendering or CPU based rendering to enhance portability across combination of OS/JVM/GPU.

The framework targets simplicity and portability across Java windowing toolkits (AWT, SWT, NEWT, Swing, JavaFX, Offscreen rendering), running either on MacOS, Windows and Linux. Jzy3d is available for other languages or platforms such as Scala, Groovy, Matlab, C#, and even Python.

The API can be used freely in commercial applications. You can explore the tutorials. an then purchase the extended developper guide to support the development effort.

How to use

Refer to the tutorial README file to get help on creating your first chart project with the help of example code.

As this library focuses on portability of the charts, the org.jzy3d.demos.surface package in jzy3d-tutorials demonstrates the same chart running on AWT, SWT, Swing using native OpenGL powered by JOGL and jGL CPU rendering.

public class SurfaceDemoAWT extends AWTAbstractAnalysis {
  public static void main(String[] args) throws Exception {
    SurfaceDemoAWT d = new SurfaceDemoAWT();
    AnalysisLauncher.open(d);
  }

  @Override
  public void init() {
    // Define a function to plot
    Mapper mapper = new Mapper() {
      @Override
      public double f(double x, double y) {
        return x * Math.sin(x * y);
      }
    };

    // Define range and precision for the function to plot
    Range range = new Range(-3, 3);
    int steps = 80;

    // Create the object to represent the function over the given range.
    final Shape surface = new SurfaceBuilder().orthonormal(new OrthonormalGrid(range, steps), mapper);
    surface.setColorMapper(new ColorMapper(new ColorMapRainbow(), surface, new Color(1, 1, 1, .5f)));
    surface.setFaceDisplayed(true);
    surface.setWireframeDisplayed(true);
    surface.setWireframeColor(Color.BLACK);

    // Create a chart
    GLCapabilities c = new GLCapabilities(GLProfile.get(GLProfile.GL2));
    IPainterFactory p = new AWTPainterFactory(c);
    IChartFactory f = new AWTChartFactory(p);

    chart = f.newChart(Quality.Advanced);
    chart.getScene().getGraph().add(surface);
  }
}

Native rendering with PanamaGL instead of JOGL

PanamaGL invokes OpenGL through the Foreign Function & Memory API of Java 22+, without JNI. It can replace JOGL for all native charts : surfaces, scatters, text, colorbars and legends, overlays, picking, offscreen rendering and screenshots, VBO, shaders, textures, volumes and depth peeling.

ChartFactory f = new PanamaGLSwingChartFactory(); // or PanamaGLJavaFXChartFactory, PanamaGLSWTChartFactory
Chart chart = f.newChart(Quality.Advanced());
chart.add(surface);
chart.open();
  • Requires Java 22+ and modules jzy3d-native-panama-gl-swing, jzy3d-native-panama-gl-javafx or jzy3d-native-panama-gl-swt.
  • Offscreen charts : f.getPainterFactory().setOffscreen(800, 600) then chart.screenshot().
  • GPU based drawables (DrawableVBO2, ScatterVBO, SphereVBO, shader mesh and waterfall, Texture3D, NativeDrawableImage, TexturedCube, ...) live in jzy3d-core and render with both JOGL and PanamaGL. They only rely on the GPU methods of IPainter and on GLConstants.
  • Depth peeling : new PanamaGLDepthPeelingChartFactory(new PanamaGLDepthPeelingPainterFactory(PeelingMethod.DUAL_PEELING_MODE)) from module jzy3d-native-panama-gl-swing, or PanamaGLDepthPeeling.enable(factory, method) for any PanamaGL chart factory.
  • Debug : setDebugGL(true) on the painter factory throws an exception on the first OpenGL error, setTraceGL(true) prints each OpenGL call.

Integration tests of jzy3d-tester-integration render the same charts with JOGL and PanamaGL and compare images (ITTest_PanamaGLParity, ITTest_GPUDrawables, ITTest_DepthPeeling). They run with PanamaGL when building with Java 22+ (profile panamagl).

What's inside

Features

Multiple chart types

  • Surface charts
  • Scatter charts
  • Volume charts
  • Bar charts
  • 3D and 2D graphs charts
  • Many primitives to build custom charts (spheres, triangles, polygons, ...)

Flexible layout

  • Colorbars
  • Colormappers for coloring objects
  • Axis box layout with detailed tick definition and tick rendering tools
  • Contour functions
  • Tooltips
  • Background images
  • 2D post renderers
  • Lights

Algorithms

  • Grid based and Delaunay surface tesselation methods
  • 3d line strip interpolation to smooth pathes (Bernstein 3d)
  • 2d envelopes (Convex hulls)
  • Polygon ordering for improved transparency rendering
  • Dual depth peeling: scene graph order independent transparency (expected for 1.0)
  • Matlab-like array processors and statistics tools
  • Experimental Support Vector Machine integration (Svm3d)

Interactions

  • Mouse interaction with objects (selection & picking methods)
  • Mouse interaction with chart (rotation, zoom, scale)
  • Key interaction with chart (rotation, zoom, scale)
  • Thread Controllers
  • Animation of objects' structures (surface, series of lines, etc)

High and low level OpenGL programming

  • Hide complexity and provide out of the box solutions for common low level OpenGL tasks
  • Fully cutomizable framework with access to all OpenGL native features through JOGL

Cross platforms and compatible

  • Straightforward integration to either AWT, Swing, Eclipse RCP (SWT), or JavaFX
  • Windows, Unix, and MacOS. Android supposed to work if enable appropriate JOGL jars
  • Offscreen rendering
  • Multiple file formats (Ply, Obj, Matlab, CSV)
  • C# port
  • Python binding
  • Scala example
  • Matlab integration

Extensions

Dependent libraries

Jzy3d depends on the following libraries that are available on Jzy3d Maven repository (See tutorials for recommended Maven setup)

  • jGL provides a pure Java implementation of OpenGL hence allowing CPU rendering as an alternative to GPU rendering (JOGL)
  • jPLY supports the PLY format for loading 3d objects
  • vecmath is a clone of a former java package

How to add to your project

The tutorial provides the code samples you need to add the library to a Maven project.

Migrate to the latest version

The jzy3d-doctor skill helps an AI agent migrate a project to the latest Jzy3d version : it finds the version in use, lists what is new since then and what the project must change, and explains how to submit an improvement to Jzy3d as a pull request. With Claude Code, copy the folder doc/skills/jzy3d-doctor to ~/.claude/skills/ (or to .claude/skills/ of the project) and ask to migrate the project to the latest Jzy3d version. Its script can also be run alone : doc/skills/jzy3d-doctor/scripts/jzy3d-versions.sh <project-dir> [jzy3d-api-clone].

Download sources & javadocs in IDE

If you did not built the framework yourself and depend on Jzy3D Maven Repository, then you may wish to see sources and javadoc in your IDE. Simply call :

mvn dependency:resolve -Dclassifier=javadoc
mvn dependency:resolve -Dclassifier=sources

How to build

A clone is about 450 MB, mostly baseline images of integration tests : see doc/repository-size.md to clone without them.

From command line

Build all

Run unit tests only

This will run all test named **/Test*.java or **/*Test.java.

mvn clean install

Run unit tests and automated integration tests

Integration tests compare charts to baseline images pixel wise. They are important in te toolbelt but have the drawback of being less portable accross computers

  • Different OS have different frame insets (changing actual rendering area size) leading to chart screenshots of different size accross OS.
  • Different OS have different frame insets (changing actual rendering area size) leading to chart a different layout (colorbar position)
  • Different OS have different font rasterization (despite using the JVM font raterizer to minimize OS impact), hence text labels do not match despite having only a few pixel difference.
  • A non HiDPI chart screenshot will not have the same size than the baseline that was generated on a Retina display (x2 pixel ratio). Integration tests that may be impacted by HiDPI are gathered in jzy3d-tester-integration since at lest Java 9 JREs are required to detect HiDPI for EmulGL charts.

This will run all test named **/ITTest*.java and unit tests. See jzy3d-tester-integration for how charts are compared to baselines, how PanamaGL is compared to JOGL, and how integration tests run on CI.

mvn clean install -Pintegration-tests

Measure the coverage of unit tests

This runs unit tests with the JaCoCo agent, then merges the coverage of all modules (a class is covered by the tests of any module) and prints it by zone (core, bindings, tools, tests, tutorials) and by module. The merged report is in target/coverage/html, the report of each module in its target/site/jacoco. See doc/coverage.md for the current coverage by zone.

mvn clean install -Pcoverage
python3 .github/scripts/coverage-by-zone.py

Skip automated tests

This will skip all tests (unit and integration)

mvn clean install -DskipTests

Manual tests

Some test require a manual verification.

Deploy

mvn deploy uploads the jars, with their sources and javadoc, to the FTP server behind maven.jzy3d.org. The server is defined at a single place, the distributionManagement of the root pom.xml :

  • its URL is read from the MAVEN_REPO_URL environment variable, e.g. ftp://ftp.example.org (without trailing /maven). Releases go to $MAVEN_REPO_URL/maven/releases, SNAPSHOT versions to $MAVEN_REPO_URL/maven/snapshots.
  • its credentials are those of the Maven server with id jzy3d-ftp.

Deploy from a local computer

Declare the credentials once in ~/.m2/settings.xml :

<settings>
  <servers>
    <server>
      <id>jzy3d-ftp</id>
      <username>your-ftp-user</username>
      <password>your-ftp-password</password>
    </server>
  </servers>
</settings>

Set the FTP server URL in the console used to deploy :

# Linux, macOS
export MAVEN_REPO_URL=ftp://ftp.example.org
# Windows PowerShell
$env:MAVEN_REPO_URL = "ftp://ftp.example.org"
:: Windows cmd
set MAVEN_REPO_URL=ftp://ftp.example.org

Then deploy, without running the tests again :

mvn deploy -DskipTests

The URL may also be given for a single command : mvn deploy -DskipTests -Denv.MAVEN_REPO_URL=ftp://ftp.example.org.

Deploy from CI

The Deploy SNAPSHOT job of the CI workflow deploys SNAPSHOT versions once all platforms passed :

  • on push to master,
  • when the workflow is started manually from the Actions page with deploy checked,
  • on pull requests labeled deploy-snapshot, to build projects depending on Jzy3d against a branch.

It runs in the jzy3d-ftp-env environment, whose secrets are set in Settings > Environments :

Secret Value Given to Maven as
FTP_URL FTP server URL, e.g. ftp://ftp.example.org MAVEN_REPO_URL environment variable
FTP_USERNAME FTP user username of server jzy3d-ftp, in the settings.xml written by actions/setup-java
FTP_PASSWORD FTP password password of server jzy3d-ftp

No settings.xml file is needed in the repository. The CI never deploys release versions.

Generate javadoc site

Comment module jzy3d-tutorial manually

mvn compile javadoc:javadoc javadoc:aggregate

From intellij

Follow these steps to import in IntelliJ

  • open an existing unrelated project
  • file->new project from version control
  • close the imported project window
  • from the unrelated project ->file-> new project from existing sources -> select the new projects location
  • from new project select top -> file -> add framework-> maven
  • file -> set module language level

From eclipse

Import Maven project or Import Maven project from SCM

How to get help

Troublshoot

JDK Mission Control

-XX:StartFlightRecording=filename=slow-init.jfr,dumponexit=true

About

A Java API for 3d and 2d charts

Topics

Resources

Stars

309 stars

Watchers

22 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages