Closed coatless closed 3 months ago
Hi James,
Try this:
<html>
<head>
<title>WebR Test Graph with Dimensions</title>
</head>
<body>
<div id="plot-output"></div>
<div>
<pre><code id="out">Loading webR, please wait...</code></pre>
</div>
<script type="module">
import { WebR } from 'https://webr.r-wasm.org/latest/webr.mjs';
const webR = new WebR();
await webR.init();
const shelter = await new webR.Shelter();
// Capture graphics with custom width/height
const capture = await shelter.captureR(`
webr::canvas(width = 320, height = 400, capture = TRUE)
.webr_cvs_id <- dev.cur()
demo(graphics)
invisible(dev.off(.webr_cvs_id))
`);
capture.images.forEach((img) => {
const canvas = document.createElement("canvas");
// set canvas size
canvas.width = img.width;
canvas.height = img.height;
// Draw image
const ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0, img.width, img.height);
document.getElementById("plot-output").appendChild(canvas);
});
shelter.purge();
</script>
</body>
</html>
If sufficient, I am happy for this to be added either in src/examples/plot-capture
or explicitly in the docs.
I am also currently reconsidering the default width
and height
for the canvas device, perhaps setting it to look at a session-wide option like getOption("webr.fig.width", default = 504)
. That would avoid the dance of creating an extra device on the stack inside captureR()
.
What are your thoughts on such a scheme?
Excellent! Just needed to add the capture = TRUE
parameter.
Thinking out loud, I don't think this should need a closing statement of dev.off()
right?
Regarding a session-wide option, I'm in favor of adding one; however, I do not believe that will be a panacea. There is a need to be able to set/customize image width and height on each call since there are already a few folks tweaking cell-level figure output in surprising ways... 😱
I don't think this should need a closing statement of dev.off() right?
It will work without dev.off()
, but including it does no harm and stops the graphics stack from growing over time if there is a long-running session..
I believe there is a limit to the number of devices on the stack, so I would actually recommend adding it. I'll edit the example to add dev.off()
now.
There is a need to be able to set/customize image width and height on each call
OK. I will keep thinking. Another option would be something like:
const capture = await shelter.captureR("demo(graphics)",
{
captureGraphicsOptions: { width: 100, height: 200 },
});
This requires thought to work well, but I needed to get 0.3.x out for other reasons. Hopefully, just opening another device will work for now. I do think we can improve this for the 0.4.x series, though.
@georgestagg I would enclose the dev.off()
in invisible()
, e.g. invisible(dev.off())
, to suppress the print statement associated with the driver.
No worries regarding the image settings. Something to have on the roadmap for 0.4.z.
One trick that could also be used in the interim with the session option is potentially resetting before each call, e.g.
webR.evalRVoid(`
options("webr.fig.width" = 320)
options("webr.fig.height" = 400)
`)
const capture = await shelter.captureR("demo(graphics)");
However, this would only work if shelter.captureR()
checked option contents on each call.
I would enclose the
dev.off()
ininvisible()
Thanks, one should probably also make an attempt to close the right device, e.g.:
webr::canvas(width = 320, height = 400, capture = TRUE)
.webr_cvs_id <- dev.cur()
demo(graphics)
invisible(dev.off(.webr_cvs_id))
With webR v0.3.0+, the graphics for
shelter.captureR()
were moved into a new.images
slot.However, it doesn't seem like there is a way to constrain image height and/or image width with a pre-call to
webr::canvas()
since the shelter makes its own call.https://github.com/r-wasm/webr/blob/cc95727742fb9324bfb35fed78480ced9648be49/src/webR/webr-worker.ts#L683-L688
So, pre-calling the
webr::canvas(width=, height=)
beforeshelter.captureR()
seems to have no effect. However, if I move the canvas call into the shelter evaluation, then the graphs are no longer stored inside of.images
, but can be retrieved through reading messages after flushing, e.g. the old way from webR v0.2.x.For a quick example, please consider the Capturing plots documentation entry with only a slight modification to
webr::canvas(height=400, width=320)
:Note this yields a series of
canvas
objects with a width and height of1008 x 1008
instead of the desired320 x 400
per imageThus, I think the
.images
slot containsimg
objects that do not respect the user supplied width and height values.