How to Publish/Subscribe Events using Custom Javascript Views

interactive
webportal
#1

We recently upgraded to KNIME Analytics Platform 4.0.2 where Plotly JS is added as possible default import in Generic JavaScript View. There are also templates present in Generic JavaScript View -> Templates tab like “2D Scatter Plot (Plotly)”, etc.

We observed that the above template uses knimeService to publish selection events. I could not find any documentation on KNIME website regarding knimeService except this knime blog - https://www.knime.com/blog/from-a-for-analytics-to-z-for-zika-virus .

Is there any documentation available on how to use knimeService and what other functions/features does it provide ?

1 Like

Tree list (with selectable nodes) from table data in Javascript View
#2

Hello @mayurin,

Thank’s for your question. At this time, the knimeService global variable isn’t fully documented. That being said, here is some commonly used functionality that’s worth mentioning:

Status Checking

  • knimeService.isInteractivityAvailable() - this will return true if the view is part of a composite view with other views (and able to pub/sub events) or false if the view is a single node view.

Notifications/Warnings

  • knimeService.setWarningMessage(msg, id) /
    knimeService.clearWarningMessage(id) /
    knimeService.clearAllWarningMessages() - these methods are available to manipulate the native KNIME warning message (usually seen in the upper right hand corner as a ‘!’ icon)

Selection/Filtering

  • knimeService.setSelectedRows(tableId, selection, callback) /
    knimeService.addRowsToSelection(tableId, selection, callback) /
    knimeService.removeRowsFromSelection(tableId, selection, callback)
    - fires an update of the selection (a JavaScript array of rowIDs) to any subscribers in the composite view. The tableId can be retrieved from the knimeDataTable and the 3rd parameter is the callback function the view used to subscribed to selection events (if applicable). The methods set the globally selected rows, add to the selected rows, or remove rows from the global selection respectively.
  • knimeService.subscribeToSelection(tableId, callback) - registers the view with any selection events published in a composite view for the provided tableId (provided by the knimeDataTable). The callback function receives an event Object which contains the update information.
  • knimeService.unsubscribeSelection(tableId, callback) - deregisters the view from reacting to selection events when they are published in the composite view. Same parameters as in the sub method.
  • knimeService.subscribeToFilter(tableId, callback, filterElement) - registers the view to receive published filter events in the same composite view. TableId is the same as for selection and the callback function receives an event Object with the updated filter information (published by the Interactive Range Slider Filter Widget, or the Interactive Value Filter Widget) and the filterElement parameter can be retrieved using the knimeDataTable.getFilterIds() method.
  • knimeService.unsubscribeFilter(tableId, callback) - deregisters the view from reacting to filter events.
  • knimeService.isRowSelected(tableId, rowId) - returns true if the rowId provided is currently selected, false if not.
  • knimeService.getAllRowsForSelection(tableId) - returns the full global set of currently selected rowIds.

Controls

  • knimeService.addMenuItem(title, icon, element, path, flags) - adds a control element to the native KNIME dropdown menu in the upper right hand corner of the view. Title is the label assigned to the menu item, icon is the String name of an icon from the Font Awesome V4.7.0 library, element is the actual element created with one of the Menu Items methods below, path is an optional parameter (passing null is fine), flags can be: knimeService.CLOSE, .OK, .CANCEL, .LINK, .SMALL_ICON or undefined/null.
  • knimeService.allowFullscreen() - creates a native KNIME ‘fullscreen’ control button in the upper right hand corner of the view if it is in a composite view which allows the user to enter fullscreen mode when it is clicked.
  • knimeService.addButton(id, icon, title, callback) - creates a native KNIME control button in the upper right hand corner of the view provided: (id) the HTML id, (icon) the String name of an icon from the Font Awesome V4.7.0 library, (title) the hover text for the button and (callback) the function to fire when the button is pressed.
  • knimeService.addNavSpacer - adds space between the most recently added button and the next button to be added with the .addButton() method.

Menu Items

(all return elements to be added to the native KNIME dropdown menu using the addMenuItem method)

  • knimeService.createMenuTextField(id, initialValue, callback, immediate)
  • knimeService.createMenuNumberField(id, initialValue, minimum, maximum, step, callback, immediate)
  • knimeService.createMenuSelect(id, initialValue, options, callback)
  • knimeService.createMenuCheckbox(id, initialState, callback, value)
  • knimeService.createMenuRadioButton(id, name, value, callback)
  • knimeService.createInlineMenuRadioButtons(id, name, initialValue, options, callback)
  • knimeService.addMenuDivider() - does not return an element, but adds a horizontal bar to space the vertical distribution of menu items in the KNIME dropdown.

Utility Functions

  • knimeService.log(message) - logs message
  • knimeService.logError(err) - logs error
  • knimeService.inlineSvgStyles(svg) - when provided an SVG element, this method applys all stylesheets available in the scope and context of the view as inline styles if possible.

So this is just a basic overview of the functionality available with the knimeService. There are a handful of other methods available on the knimeService object that I didnt cover here. If you plan on using it extensively in the Generic JavaScript View node or in custom visualization nodes, I would recommend you read through the source to get a better idea of what else is available here. As for official documentation, we are hoping to continue to improve the documentation as best as possible. In the meantime, I hope this overview helps :slight_smile:

Best,
-Ben

8 Likes

#3

Hello @blaney ,

Thank you very much for the details.
I could use selection events publish/subscribe api from knimeService to create interactive exploration view and it works perfect.

I was wondering if it is possible to publish filter events using knimeService. For some of user experience requirements, we wish to publish filters using custom view(instead of Value Filter). Do you have any suggestions ?

0 Likes

#4

Hey @mayurin,

Glad the info was helpful and really cool that you got the selection events working :slight_smile: Currently, you can use either the “Interactive Value Filter Widget” (for Nominal Filtering) or the “Interactive Range Slider Filter Widget” (for Range-based filtering) with many of our existing visualization nodes. If you want to filter NOMINAL or RANGE based tables with custom implementations via the Generic JavaScript View, I would check out the source here for inspiration.

With the existing functionality you can use functionality provided by the knimeDataTable API to apply the filter to the data table in the view. Check out the source for that API here. Methods like isValueIncludedInFilterElementRangeand isRowIncludedInFilter make it really simple to apply the filters matching the existing filter API to the data within a view.

I hope this helps! :slight_smile:

Of course, if you want to get tricky and implement your own custom filters, this is possible too. For an example, I hacked together a searchable column filter using two “Generic JavaScript View” nodes within a component (attached at the bottom of this post). I used the “Plotly Scatter Plot” template available from the node as a starting point for the visualization and then vanilla JavaScript and the knimeService API to implement some custom controls.

This allows you to filter out rows based on the letter in the input field. At the end of the day, the knimeService API acts as a general Pub/Sub service provider, so once you get the tableIds matched up, you can create more in depth filters or interactions as needed.

Let me know if you have any questions!

Best,
Ben

sample_searchable_filter.knwf (460.6 KB)

3 Likes

#5

Hello @blaney ,

Thank you for the example workflow. It works nicely on its own but if I add Table View in same component, it does not filter the Table View.
The custom selection views which publish selection events work with existing knime views like Table View or Scatter Plot view. However custom filter views(including the view you have shared in example workflow) do not appear to work with these knime views. This limits usage of existing knime views with custom filter views. Is my understanding correct?

0 Likes

#6

Hey @mayurin,

You’re right in that truly custom filter events like the one in the example will not be registered by existing KNIME visualization nodes. The example I made uses RowIDs to filter the data in the custom visualization (scatter plot). You can create filter events using the already implemented API which supports Range and Nominal filter events. In the image below (taken from the Generic JavaScript View node in the example) you can see the format of the filter event published by the custom filter. As mentioned in the notes, you can change the type to 'numeric' or 'nominal' and replace the rowIds key with minimum and/or maximum along with minimumInclusive or maximumInclusive (for type: 'numeric') OR a values key (for type: 'nominal'; set equal to an Array of values to filter).

These filter types are supported by existing KNIME visualization nodes, so they should react to published events if they share the same tableId. Of course, be sure to read the node descriptions of any nodes you use to make sure they support filters :slight_smile:.

As for rowId based filter events- this is functionality we hope to add in the near future. You can simulate the filter in the example by using a nominal filter to filter by letters, so there are ways to achieve the same functionality with existing nodes.

Hope this helps!

Best,
Ben

0 Likes