JavaScript API updates

Let’s use this topic for reporting and discussing new Datagrok JavaScript API features.
They become available on http://dev.datagrok.ai/ at the time of the topic update.

We’ve added support for manipulating Datagrok .temp and .tags available for dataframes and columns. Now they can be manipulated just as one does with JavaScript’s Map or object properties (both API conventions are supported). For instance, here is how to iterate through the tags, print them to the browser’s console and then delete one key:

let demog = grok.data.demo.demog();
demog.tags.foo = 'bar';
for (const [key, value] of demog.tags)
  console.log(key, ':', value);
if ('foo' in demog.tags)
  delete demog.tags.foo;
grok.shell.info(`foo is present: ${demog.tags.has('foo')}`);

Try out the means to iterate and manipulate .tags and .temp collections in this example on Datagrok.

2 Likes

We’ve added functionality to manipulate files using grok.dapi.files.
At the moment you can use following list of file operations:

  • write(file, blob)

    await grok.dapi.files.write('Demo:TestJobs:Files:DemoFiles/testFile.dat', [0, 1, 2]);

  • writeAsText(file, data)

    await grok.dapi.files.writeAsText('Demo:TestJobs:Files:DemoFiles/testFile.txt', 'testString');

  • readAsBytes(file)

    await grok.dapi.files.readAsBytes('Demo:TestJobs:Files:DemoFiles/testFile.dat')

  • readAsText(file)

    await grok.dapi.files.readAsText('Demo:TestJobs:Files:DemoFiles/testFile.txt')

  • exists(file)

    await grok.dapi.files.exists('Demo:TestJobs:Files:DemoFiles/testFile.dat');

  • rename(file, newName)

    await grok.dapi.files.rename('Demo:TestJobs:Files:DemoFiles/forRename.txt', 'renamed.txt');

  • list(file, recursive, searchPattern)

    let recursive = true;
    let searchPattern = 'world';
    res = await grok.dapi.files.list('Demo:TestJobs:Files:DemoFiles/geo', recursive, searchPattern);
    
  • move(files, newPath)

    await grok.dapi.files.move(['Demo:TestJobs:Files:DemoFiles/testFile.txt'], 'geo');

  • delete(file)

    await grok.dapi.files.delete('Demo:TestJobs:Files:DemoFiles/testFile.dat');

Note, that these functions return promises you have to handle using async/await or .then chain.

You can take a look on JS API samples here to be sure you use API correctly and launch your own as js scripts on the platform.

1 Like

We have exposed the JS API for value matchers. See the following link for examples of all matchers (numerical, string, date, bool): https://datagrok.ai/help/explore/data-search-patterns

Or play around with the following example: https://dev.datagrok.ai/js/samples/data-frame/value-matching/value-matcher

let matcher = DG.ValueMatcher.numerical('> 30');

grok.shell.info(matcher.operator);      // '>'
grok.shell.info(matcher.match(40));     // true
grok.shell.info(matcher.validate(20));  // "> 30" does not match "20"
2 Likes

We added an event subscription API for Grid column and rows resize. Datagrok will be sending events on resize with properties to identify if resize is still in progress or just ended (ev.args.dragging) and which column gets resized (ev.args.column).

Code example:

let grid = grok.shell.addTableView(grok.data.demo.demog()).grid;

grid.onRowsResized.subscribe((ev) => {
  let status = ev.args.dragging ? "dragging" : "done";
  grok.shell.info("Resizing row height: " + status);
});

grid.onColumnResized.subscribe((ev) => {
  let status = ev.args.dragging ? "dragging" : "done";
  grok.shell.info(`Resizing ${ev.args.column.name}: ` + status);
});

[https://github.com/datagrok-ai/public/blob/master/packages/ApiSamples/scripts/grid/resize-events.js]

@dpetrov.gnf.org @andreas.gasser.novartis.com

2 Likes

Today we are introducing an important new feature - the ability to provide custom value comparison function that is used for sorting the column. The following script demonstrates the concept, all that is needed is to set column.valueComparer:

// Providing custom comparer function

// Let's say we have a string column where values have some logical order
let column = DG.Column.fromList(DG.TYPE.STRING, 'months', ['Feb', 'Jan', 'May', 'Mar']);

// Define and set a custom value comparer that is used for sorting later
let months = { Jan: 1, Feb: 2, Mar: 3, Apr: 4, May: 5 };
column.valueComparer = (s1, s2) => months[s1] - months[s2];

// It is possible to get the sorted order if needed
let order = column.getSortedOrder();
grok.shell.info(Array.from(order).map((i) => column.get(i)).join(', '));

// Or, simply double-click on the header to sort it visually
grok.shell.addTableView(DG.DataFrame.fromColumns([column]));

Once a value comparer is defined for a column, it gets used by all visualizations, and for other purposes such as aggregation as well. Check out the screenshot below (a result of running the script above) and note the proper sorted order on all charts:

@nico.pulver.novartis.com, @nikolaus.stiefl.novartis.com, @ptosco, @timothy.danford.novartis.com - I believe you have plenty of applications for that feature :slight_smile:

2 Likes

That’s really cool, Andrew, thanks a lot!
We will need that to support custom sorting by the user’s list of favorite compound ids.