Chapter 10. Concepts for use in specialized plugins

This chapter contains information on some topics that are useful only to certain classes of plugins.

Plugins that produce a plot

Creating a plot from a plugin is easy to do. However, there are a few subtle gotchas to avoid, and also some great generic functionality that you should be aware of. This section shows you the basic concepts, and concludes with a canonical example that you should follow whenever creating plot plugins.

Drawing a plot to the output window

In order to draw a plot to the output window, use rk.graph.on() directly before creating the plot, and rk.graph.off(), directly afterwards. This is similar to e.g. calling postscript() and dev.off() in a regular R session.

Importantly, however, you must always call rk.graph.off() after calling rk.graph.on(). Otherwise the output file will be left in a broken state. To ensure rk.graph.off() really gets called, you should wrap all R commands between the two calls in try() statement. Never heard of that? Don't worry, it's easy. All you need to do is follow the pattern shown in example, below.

Adding preview functionality

Note

This section discusses adding preview functionality to plugins producing plots. There are separate sections on previews of (HTML) output, previews of (imported) data, and custom previews. However, it is recommended that you read this section first, as the approach is similar in each case.

A very useful feature for all plugins generating a plot/graph is to provide an automatically updating preview. To do so, you will need two things: Adding a <preview> check box to your GUI definition, and adjusting the generated code for the preview.

Adding a <preview> check box is simple. Just place the following somewhere in your GUI. It will take care of all the behind-the-scenes magic of creating a preview device, updating the preview whenever the setting have changed, etc. Example:

Note

Starting with version 0.6.5 of RKWard <preview> preview elements are special-cased in plugin dialogs (not wizards): They will be placed in the button-column, irrespective of where exactly they are defined in the UI. It is still a good idea to define them at a sensible place in the layout, for backwards compatibility.

	<document>
		[...]
		<dialog [...]>
			[...]
			<preview id="preview"/>
			[...]
		</dialog>
		[...]
	</document>
		

And that's it for the GUI definition.

Adjusting the JS template is a little more work. You will have to create a new function called preview() in addition to the preprocess(), calculate(), etc. functions. This function should generate the code needed to produce the plot, and only that. Esp. no printing of headers, rk.graphics.on(), or similar calls. See the example, below for the typical pattern that you will use.

Generic plot options

You will have noticed that most plotting plugins in RKWard provide a wide range of generic options e.g. for customizing axis titles or figure margins. Adding these options to your plugin is easy. They are provided by an embeddable plugin called rkward::plot_options. Embed this in your plugin UI like this:

	<document>
		[...]
		<logic [...]>
			<connect client="plotoptions.xvar" governor="x.available"/>
			<set id="plotoptions.allow_type" to="true"/>
			<set id="plotoptions.allow_ylim" to="true"/>
			<set id="plotoptions.allow_xlim" to="false"/>
			<set id="plotoptions.allow_log" to="false"/>
			<set id="plotoptions.allow_grid" to="true"/>
		</logic>
		<dialog [...]>
			[...]
			<embed id="plotoptions" component="rkward::plot_options" as_button="true" label="Plot Options"/>
			[...]
		</dialog>
		[...]
	</document>
		

This will add a button to your UI to bring up a window with plot options. The logic section is just an example. It allows you some control over the plot options plugin. Read more in the plot_options plugin's help page (linked from the help page of any plugin providing the generic options).

Next you need to make sure that the code corresponding to your plot options is added to the generated code for your plot. To do so, fetch the properties code.preprocess, code.printout, and code.calculate from the embedded plot options plugin, and insert them into your code as shown in the example, below.

A canonical example

Here's an example .JS file that you should use as a template, whenever you create a plotting plugin:

  function preprocess () {
    // the "somepackage" is needed to create the plot
    echo ("require (somepackage)\n");
  }

  function preview () {
    // we call all stages of the general code. Only the printout () function needs to be called slightly different for the plot preview
    preprocess ();
    // calculate (); // in this example, the plugin has no calculate () function.
    printout (true); // in this case, 'true' means: Create the plot, but not any headers or other output.
  }
  
  function printout (is_preview) {
    // If "is_preview" is set to false, it generates the full code, including headers.
    // If "is_preview" is set to true, only the essentials will be generated.

    if (!is_preview) {
      echo ('rk.header (' + i18n ("An example plot") + ')\n\n');
      echo ('rk.graph.on ()\n');
    }
    // only the following section will be generated for is_preview==true

    // remember: everything between rk.graph.on() and rk.graph.off() should be wrapped inside a try() statement:
    echo ('try ({\n');
    // insert any option-setting code that should be run before the actual plotting commands.
    // The code itself is provided by the embedded plot options plugin. printIndentedUnlessEmpty() takes care of pretty formatting.
    printIndentedUnlessEmpty ('\t', getString ("plotoptions.code.preprocess"), '', '\n');

    // create the actual plot. plotoptions.code.printout provides the part of the generic plot options
    // that have to be added to the plotting call, itself.
    echo ('plot (5, 5' + getString ("plotoptions.code.printout") + ')\n');

    // insert any option-setting code that should be run after the actual plot.
    printIndentedUnlessEmpty ('\t', getString ("plotoptions.code.calculate"), '\n');
    echo ('})'\n);  // the closure of the try() statement

    if (!is_preview) {
      echo ('rk.graph.off ()\n');
    }
  }