-
Notifications
You must be signed in to change notification settings - Fork 39
Scope (Plugin) Architecture
While initially motivated by the needs of plotly.py, Kaleido is designed to make it fairly straightforward to add support for additional web-based visualization libraries. Plugins in Kaleido are called "scopes".
We hope to collaborate with many other web-based visualization libraries to finally solve this problem across the web-based visualization community.
This section describes the current requirements for adding a new scope (with Python support) for a new visualization library. This section will assume that the new library is named superviz
.
First add a new Python class named SupervizScope
to a new file at repos/kaleido/py/kaleido/scopes/superviz.py
. This class should subclass BaseScope
. It must implement the constructor and override the scope_name
property to return the string 'superviz'
. The constructor should accept and validate any global configuration values the library needs. In particular, this may include the path/URL of the superviz.js
library.
See repos/kaleido/py/kaleido/scopes/plotly.py
for a reference example.
Add a new SupervizScope
C++ class to a new header file at repos/kaleido/cc/scopes/Superviz.h
. This class should subclass BaseScope
. It must override the ScopeName
method to return the string "superviz"
. In the constructor, it should look for command-line switches that correspond to the global configuration values above. These switches will have identical names to the Python variables defined above, but with underscores replaced by hyphens. The scriptTags
list property should be updated with the <script>
tag URLs that should be included in the initial HTML document. The localScriptFiles
list property should be updated with the paths of local JavaScript files to load dynamically after the initial HTML document has been loaded.
It must also override the BuildCallArguments
method. This method is responsible for returning a std::vector
of chromium CallArguments
. These should correspond to the same global configuration parameters, but here the order is significant, so choose an order that matches the argument order of the JavaScript render
method described below.
See repos/kaleido/cc/scopes/Plotly.h
for a reference example.
Update the LoadScope
function in repos/kaleido/cc/scopes/Factory.h
so that an instance of the SupervizScope
class is returned when the input string is "superviz"
.
Next, add a new render
JavaScript function to a new file at repos/kaleido/js/src/superviz/render.js
. The first argument to this function will be a JavaScript object that corresponds to the arguments to the BaseScope.transform
Python method. For the Plotly scope these are data
, format
, width
, height
, and scale
. The second through last argument will match the arguments constructed in the BuildCallArguments
C++ method above.
This function is responsible for returning a Promise
that resolves to an object that includes the result of the image export attempt. The object should have the following properties
-
code
: If an error occurred, the code should be a non-zero integer and an associatedmessage
should be included that describes the error. If export was successful,code
should be0
-
message
: If an error occurred, this should be a string containing the error message. If export was successful,message
should benull
-
result
: The image export result as a string. All formats exceptsvg
should be base64 encoded. Special Case: If the input format ispdf
, then therender
function should choose the most appropriate image format that will be embedded in pdf (e.g.svg
) and instead of returning aresult
, it should set this image as thesrc
property of the<img>
tag with idkaleido-image
. -
format
,width
,height
,scale
: The format, width, height, and scale factor that were used. Even though these values are inputs, therender
function may supply its own defaults and whatever values were actually used to generate the image should be included here. If the input format waspdf
, then theformat
returned here should be whatever image format was used to generate the image that will be embedded in the PDF. e.g.svg
. -
pdfBgColor
: If theformat
ispdf
, this property should contain the desired background color of the figure. It is recommended that, if possible, the background color the associated figure image be set to fully transparent so that the PDF background color will fully show through. Ifformat
was not'pdf'
this property should be set tonull
.
Additional JavaScript helper functions can be added to the repos/kaleido/js/src/superviz/
directory. The JavaScript files are bundled using browserify
on build. Additional NPM dependencies can be added to repos/kaleido/js/package.json
. Note that the visualization library itself shouldn't be added as an NPM dependency, this is because we want to keep the resulting JavaScript bundle as small as possible, and we don't want to have to release a new version of Kaleido for each release of the various visualization libraries. Instead, the visualization libraries should be loaded from a CDN url by default and added to scriptTags
above. To support offline use, it is also helpful to support loading the visualization library from a local JavaScript file, adding the path to localScriptFiles
instead.
See repos/kaleido/js/src/plotly/render.js
for a reference example.
Update the module.exports
section of repos/kaleido/js/src/index.js
to include:
superviz: require("./superviz/render")
As support is added for additional language wrappers (other than Python), a new scope class/interface will be needed for each wrapper language. If stored in this repository, these wrappers should be added to the repos/kaleido/{language_name}/
director.
This scope architecture will surely evolve over time as support is added for additional libraries. Once we get experience with additional libraries, it may be possible for scopes to be specified entirely in JavaScript + Python, without requiring C++ changes.
Additionally, we may want to extend this architecture to more naturally support non-image transform operations.