Skip to content
Snippets Groups Projects
Commit d9f598f8 authored by Stepan Sindelar's avatar Stepan Sindelar
Browse files

[GR-2798] Few small grid fixes and graphics documentation.

parents 86b6e7e0 27590351
No related branches found
No related tags found
No related merge requests found
......@@ -30,12 +30,16 @@ import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.r.library.fastrGrid.GridState.GridDeviceState;
import com.oracle.truffle.r.library.fastrGrid.device.GridDevice;
import com.oracle.truffle.r.library.fastrGrid.device.GridDevice.DeviceCloseException;
import com.oracle.truffle.r.library.fastrGrid.device.SVGDevice;
import com.oracle.truffle.r.library.fastrGrid.device.awt.BufferedImageDevice;
import com.oracle.truffle.r.library.fastrGrid.device.awt.BufferedImageDevice.NotSupportedImageFormatException;
import com.oracle.truffle.r.library.fastrGrid.graphics.RGridGraphicsAdapter;
import com.oracle.truffle.r.runtime.FastRConfig;
import com.oracle.truffle.r.runtime.RCaller;
import com.oracle.truffle.r.runtime.RError;
import com.oracle.truffle.r.runtime.RError.Message;
import com.oracle.truffle.r.runtime.RInternalCode;
import com.oracle.truffle.r.runtime.RInternalError;
import com.oracle.truffle.r.runtime.context.RContext;
import com.oracle.truffle.r.runtime.data.RFunction;
import com.oracle.truffle.r.runtime.env.REnvironment;
......@@ -97,6 +101,14 @@ public final class GridContext {
} else {
setCurrentDevice(defaultDev, WindowDevice.createWindowDevice());
}
} else if (defaultDev.equals("svg")) {
setCurrentDevice(defaultDev, new SVGDevice("Rplot.svg", GridDevice.DEFAULT_WIDTH, GridDevice.DEFAULT_HEIGHT));
} else if (defaultDev.equals("png")) {
setCurrentDevice(defaultDev, safeOpenImageDev("Rplot.png", "png"));
} else if (defaultDev.equals("bmp")) {
setCurrentDevice(defaultDev, safeOpenImageDev("Rplot.bmp", "bmp"));
} else if (defaultDev.equals("jpg") || defaultDev.equals("jpeg")) {
setCurrentDevice("jpeg", safeOpenImageDev("Rplot.jpg", "jpeg"));
} else {
throw RError.error(RError.NO_CALLER, Message.GENERIC, "FastR does not support device '" + defaultDev + "'.");
}
......@@ -132,6 +144,14 @@ public final class GridContext {
return RContext.getEngine().evalFunction(redrawAll, REnvironment.baseEnv().getFrame(), RCaller.topLevel, true, null, args);
}
private BufferedImageDevice safeOpenImageDev(String filename, String formatName) {
try {
return BufferedImageDevice.open(filename, formatName, GridDevice.DEFAULT_WIDTH, GridDevice.DEFAULT_HEIGHT);
} catch (NotSupportedImageFormatException e) {
throw RInternalError.shouldNotReachHere("Device format " + formatName + " should be supported.");
}
}
private static final class DeviceAndState {
final GridDevice device;
final GridDeviceState state;
......
......@@ -182,6 +182,7 @@ public class Graphics2DDevice implements GridDevice {
void setGraphics2D(Graphics2D newGraphics) {
assert newGraphics != null;
graphics = newGraphics;
cachedContext = null;
}
public Graphics2D getGraphics2D() {
......
......@@ -22,6 +22,7 @@ import com.oracle.truffle.r.runtime.ROptions.OptionsException;
import com.oracle.truffle.r.runtime.RRuntime;
import com.oracle.truffle.r.runtime.context.RContext;
import com.oracle.truffle.r.runtime.data.RDataFactory;
import com.oracle.truffle.r.runtime.data.RNull;
import com.oracle.truffle.r.runtime.data.RPairList;
import com.oracle.truffle.r.runtime.env.REnvironment;
......@@ -64,9 +65,14 @@ public final class RGridGraphicsAdapter {
public static void initialize() {
addDevice(NULL_DEVICE);
setCurrentDevice(NULL_DEVICE);
ROptions.ContextStateImpl options = RContext.getInstance().stateROptions;
RContext ctx = RContext.getInstance();
ROptions.ContextStateImpl options = ctx.stateROptions;
if (options.getValue(DEFAULT_DEVICE_OPTION) != RNull.instance) {
return;
}
String defaultDevice = ctx.isInteractive() ? "awt" : "svg";
try {
options.setValue(DEFAULT_DEVICE_OPTION, "awt");
options.setValue(DEFAULT_DEVICE_OPTION, defaultDevice);
} catch (OptionsException e) {
RError.warning(RError.NO_CALLER, Message.GENERIC, "FastR could not set the 'device' options to awt.");
}
......
......@@ -7,3 +7,5 @@
[For Developers](dev/Index.md)
[Debugging](debugging.md)
[Graphics support](graphics.md)
# Introduction
There are two main built-in R packages that provide basic graphical output
support: *graphics* and *lattice*. They both use some parts of even lower level
*grDevices* package, which allows users to change the "device" to which the
graphical output will be drawn. The probably most popular graphical packages
*lattice* and *ggplot2* are build on top of the *grid* package.
FastR has its own implementation of the *grid* package and it also emulates
the most important R level functions from the *grDevices* package. This
implementation is purely Java based and has been tested to work with
the unmodified *lattice* package, support for unmodified *ggplot2* package
is work in progress.
Any functions from the *graphics* package are not going to work with FastR,
namely e.g. the `plot` function. R documentation, which can be displayed by
typing `?functionName` can be used to determine if a function is from *graphics*
or *grid* package or potentially from some *grid* based higher level package.
The longer term goal is to emulate R level *graphics* package functions by
means of *grid* package drawing primitives.
# Examples
The *grid* package is distributed with FastR, but not loaded by default,
therefore one has to load it using the `library` function. Following example
draws a red rectangle in the center of the screen.
```
library(grid)
grid.rect(width=0.5, height=0.5, gp=gpar(col='red'))
```
The *lattice* package must be installed using:
```
install.packages('lattice');
```
With the *lattice* package installed, one can run the
following example showing a barchart.
```
library(lattice)
mtcars$cars <- rownames(mtcars)
barchart(cars~mpg, data=mtcars)
```
# Devices Support
FastR supports the following devices:
* awt: opens a new AWT window for drawing, the window can be resized and
its contents can be saved with the standard `savePlot` function.
This is the default device for interactive sessions.
In FastR, for compatibility with GNU R, *X11* device is alias for the *awt* device.
* svg: generates SVG image, which is saved into a specified file.
The contents may be read into a character vector by FastR specific function
`grDevices:::svg.off()`. FastR produces the SVG code directly from *grid* drawing commands,
therefore the SVG code may look more SVG idiomatic and resembling the R code that created it,
but may produce visually slightly different image compared to other devices.
This device is default for non-interactive FastR sessions.
* jpg, png, bmp: these devices create an image file of specified format. Unlike the SVG device,
these are also based on the AWT framework.
Devices that generate file take filename as an argument. The file will be saved on disk only
once the standard `dev.off()` function is called. FastR honors the "device" option, which
may override the default device. See the documentation of *grDevices* package for more details.
# Java Interoperability
The `grDevices::awt` function can accept `java.awt.Graphics2D` object and width and height in AWT units,
in which case all the drawing will be done using that object. Example:
```
grDevices:::awt(420, 420, graphicsObj);
```
One possible use case is to create a Java based UI with a `JPanel` that will be
used for visualizing some data from R. Override the `JPanel`'s `paint`
method and pass the graphics object to R code using `PolyglotEngine`.
The R code can do any *grid* based visualization and it will be directly
displayed in the UI.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment