Reading time: 8 minutes and 45 seconds.
What's new?
No matter which mods API version you want to target, you should always use the latest compatible version of the NPM packages:
- @spotfire/mods-api - Use the latest patch version for the mods API you are targeting.
- @spotfire/mods-sdk
- @spotfire/mods-dev-server
If you have started from an SDK template, simply run npm update to get the latest compatible versions.
Mods API 2.2
Version 2.2 of the mods API introduces optional axes to visualization mods, as well as exposing new action mods APIs for working with reference layers. Using API features introduced in the 2.2 API requires Spotfire version 14.6 or later. To upgrade an existing mod, follow these steps:
- Update the
"apiVersion"version in the mod manifest to"2.2". - Update the version of
"@spotfire/mods-api"in thepackage.jsonfile to~2.2.0. - Run
npm update.
Action mods
No new additions to the action mods framework has been added however, Spotfire 14.6 introduces many new features which are supported in the API. One such feature is the new “reference elements” feature, which allows you to add reference layers such as trend lines to certain visualizations. As an example on how to use the new APIs for this feature, see the snippet “Add a reference layer showing trend lines”.
Visualization mods
Version 2.2 of the visualization mods API adds the ability to mark an axis “optional”.
This can be done by setting the "optional" property of the axis object in the manifest to true.
An axis marked optional indicates that it should not be displayed in the new visualization properties panel when in an unconfigured state.
It also makes it possible to clear the axis expression by removing the card from the visualization properties panel if it has been configured.
To control the automatic configuration of an optional axis, the API also introduces the "disableOnAutoConfigure" property on the "automaticConfiguration" object.
An optional axis with a defined automatic configuration will be configured when the mod visualization is initially added to the document.
By setting "disableOnAutoConfigure" to false, the axis will only be automatically configured when its axis card is added in the visualization properties panel.
Mods API 2.1
Version 2.1 of the mods API contains many improvements to both action mods and visualization mods. Using API features introduced in the 2.1 API requires Spotfire version 14.5 or later. To upgrade your mod, follow these steps:
- Update the
"apiVersion"field in the manifest to"2.1". - Update the version of
@spotfire/mods-apiin thepackage.jsonfile to~2.1.0. - Run
npm update.
Action mods
Version 2.1 of the API contains a lot of improvements and new features for action mods.
New parameter types
This API introduces two new types with two variants each: DataColumn (array: true/false) and DataViewDefinition (singleColumn: true/false). Additionally, it is now possible to define parameters as optional (see Optional), to limit numerics to a range (see Numeric ranges), and to specify a set of allowed values for string parameters (see Enum).
DataColumn
Scripts can now define DataColumn as a possible parameter type.
This can be done by setting "type": "DataColumn" for the parameter in the manifest.
Defining a parameter of this type will allow you to select a column from an existing data table during configuration or when the parameter is prompted.
Data column parameters are useful in scripts which previously required a GUID or column name as a parameter.
Previously you had to pass a GUID or string to DataColumnCollection.TryGetValue and check that the method returned true, likely throwing an error if not.
This was clunky, required writing boilerplate code, and prone to input errors such as misspelling the column name or entering an incorrect GUID.
Take for instance the “Read the values of a column” snippet which previously started with this code:
export function readColumnValues({ document, table, column }: ReadColumnValuesParameters) {
const dataColumn = OutParam.create(DataColumn);
if (!table.Columns.TryGetValue(column, dataColumn.out)) {
throw new Error(`Data table '${table.Name}' contains no column with name '${column}'.`);
}
// ...
}
By changing the column parameter type from "String" to "DataColumn", this code can be completely removed.
The table parameter is no longer necessary because it can be retrieved via the column’s document node context.
See the snippet for the updated code and manifest.
The new DataColumn type also supports setting property "array": true to allow multiple columns as a value.
When configured as an array, the script argument will have type Iterable<DataColumn> and can be consumed by the script via for ... of loops or functions which operate on iterables such as Array.from.
Additionally, the set of possible columns that the user is allowed to choose from can be limited by specifying allowedDataTypes. For example, to limit to only integer, columns set "allowedDataTypes": ["Integer"].
DataViewDefinition
Scripts can now define DataViewDefinition as a possible parameter type.
This can be done by setting "type": "DataViewDefinition" for the parameter in the manifest.
Defining a parameter of this type can be configured by selecting columns, a column search expression, or a custom expression.
The data view definition can also contain a number of limitations, such as limit by marking or filtering scheme (unless "disableLimitations": true is set in the manifest).
A data view definition is a comma separated list of column expressions.
The data view can be limited to only a single column expression by setting the "singleColumn": true property.
The main purpose of this parameter is to be passed along to data functions. This is made possible by a new overload of DataFunctionInputCollection.SetInput which takes a ActionDataViewDefinition as its second argument, as an example see snippet “Add a data function using a data view definition”.
Optional
A parameter can be marked as optional by defining "optional": true.
When a parameter has been defined as optional, it is not necessary to provide an input value during configuration.
Adding optional parameters to existing scripts does not invalidate existing configurations.
When defining a parameter of some type T as optional the argument will be typed as T?, meaning that the value may either be provided or undefined.
Optional parameters are a great way to update existing scripts without breaking existing usages (the API will remain stable). They can also be used to reduce the amount of configuration in cases where you can assume some default value for an optional parameter.
Enum
You can now limit string parameters to allow specific values by specifying "enum": ["Value 1", "Value 2"].
A string parameter limited in this way will provide the user with a drop-down list of the available options during configuration.
Adding a value to an existing enum will not invalidate existing configurations and will therefore not break existing usages.
Numeric ranges
Numeric parameters can now be restricted to a specified range in the manifest.
For instance, for a Real that is used to represent a value between 0% and 100%, you can restrict the parameter to that range by defining "range": { "min": 0, "max": 1 }.
Another useful range would be an Integer used to represent a count starting from 0.
This can be achieved by specifying "range": { "min": 0 }.
For more information, see the parameter documentation for Numerics.
New APIs
Some new and previously existing .NET APIs have now been made available to action mods. These include:
- Adding image layers to map charts via MapChartLayerCollection.AddNewImageLayer. This API can be used in combination with a mod resource, see “Add resources to your action mod” below.
- Loading STDF data via the Data.Format.Stdf APIs, see snippet “Create a table using the STDF APIs”.
- Looping through each descendant of a document node with a specified type via DocumentNode.ForEachNodeInSubTree. This is a very powerful API for making large updates to the document, see for instance the “Modify all expressions in every visualization” snippet.
- Add data functions to the document and configure them via DataFunctionCollection, DataFunctionInputCollection, and DataFunctionOutputBuilder. Note that the new DataViewDefinition type can be passed to a data function via the DataFunctionInputCollection.SetInput API.
- Creating and configuring visualizations from the visualization mods maintained by the ModManager. This includes loading visualizations from the library. See snippet “Add Latest Mod Visualization”.
Add resources to your action mod
File resources, specified using the files property in the manifest, can now be accessed as Streams inside a script.
Specifying the path relative to manifest in the files field will include the file in the mod, the mod can then be accessed via the resources parameter provided to every script’s entry point function.
Let’s try to add a PNG image to a text area on the active page.
-
Create a
staticfolder in your mod project next to the manifest. -
Add a PNG image in the folder called
my-image.png. -
In the manifest, reference your image by adding
"files": ["static/my-image.png"].All scripts in the mod should now be provided with a
resourcesparameter. If you have the SDK build watcher running you can see this in theenv.d.tsfile. -
Create a new script via
npx @spotfire/mods-sdk add-script add-image-to-text-areaand open the script file.
If you are using the latest SDK, the entrypoint should automatically destructure the resources field from the parameter object.
For existing scripts, simply add resources after document.
Our image can now be retrieved via resources.LoadResource("static/my-image.png").
This method returns a Stream, which is a type accepted by many APIs.
Let’s modify the script so that it creates a text area, adds the image to the text area’s image collection, and displays it as HTML.
The script should look like this:
const { HtmlTextArea } = Spotfire.Dxp.Application.Visuals;
export function addImageToTextArea({ document, application, resources }: AddImageToTextAreaParameters) {
const page = document.ActivePageReference;
if (!page) {
throw new Error(`Cannot create a text area without an active page`);
}
const textArea = page.Visuals.AddNew(HtmlTextArea);
textArea.Images.Add("my-image", resources.LoadResource("static/my-image.png"));
textArea.HtmlContent = `<img src="my-image" />`;
textArea.Title = "Text are containing an image";
}
RegisterEntryPoint(addImageToTextArea);
Spotfire previously used to re-fetch the entire mod on any file update, which would cause performance to slow down when mods with large resource files were developed. Make sure you are using version 1.2 or later of mods-dev-server to allow Spotfire to only fetch the files that have actually changed.
Unique icon per script
Each script can now specify its own unique SVG icon, which will show up in various parts of the UI such as floating buttons, title bar buttons, and in the Actions flyout.
Scripts that do not specify an icon will fall back to the icon of the action mod.
To specify an icon, add an "icon": "path/to/icon.svg" property to the script in the manifest.
Visualization mods
Version 2.1 of the API also contains some smaller improvements to visualization mods.
Axis expression heuristics
When a new instance of a visualization mod is created, heuristics are used to assign initial expressions to the axes of the visualization.
You can now specify a string, like count(), to use as the initial expression. This is made in the automaticConfiguration/expressionHeuristics
property of an axis specification in the manifest.
When the default heuristics are used for a continuous axis, the allowNonAggregatingMeasures can be set to "prefer" to control the heuristics to attempt to select
an expression that is not aggregating.
More styling information
The StylingInfo object has been extended with more information describing the current theme. For instance regarding how zoom sliders and trellis panel headers are styled.