Integrate using the TypeScript driver
It is possible to control Gephi Lite in a tab or an iframe from another web page. This feature uses the browser Broadcast Channel API.
The main constraint of the BroadcastChannel
API is that both the controlling web page and the controlled Gephi Lite must be hosted on the same domain. Please read the Deploying Gephi Lite documentation page to know more on how to host Gephi Lite on your servers.
To ease communicating with Gephi Lite, you can use the @gephi/gephi-lite-broadcast
NPM project from your TypeScript or JavaScript codebase. At the moment, this driver supports:
- Read or import a Graphology graph
- Read or set the
SerializedGraphDataset
object (that fully describes the dataset) - Read or set the
AppearanceState
object (that describes everything from the Appearance menus in Gephi Lite) - Read or set the
FiltersState
object (that describes the filters)
Example
The easiest way to dive into how to use the driver, is to look at how Gephi Lite itself uses it! Indeed, Gephi Lite offers users to clone their current workspace in a new tab, using the @gephi/gephi-lite-broadcast
package. This allows duplicating a graph to compare two different appearance setups, for instance - or also "saving" a state before applying some destructive modifications...
So, let's see how Gephi Lite uses the driver:
// This is the driver class, that allows all that:
import { GephiLiteDriver } from "@gephi/gephi-lite-broadcast";
// These are some internal Gephi Lite typings:
import {
AppearanceState,
FiltersState,
GraphDataset,
} from "@gephi/gephi-lite-sdk";
export async function openInNewTab({
dataset,
appearance,
filters,
}: {
dataset: GraphDataset;
appearance: AppearanceState;
filters: FiltersState;
} = {}) {
// 1. Instanciate GephiLiteDriver (no name is given, so a random UUID will be
// used instead):
const driver = new GephiLiteDriver();
// 2. Open a new Gephi Lite in a new tab, and wait for it
await driver.openGephiLite({ baseUrl: location.pathname });
// 3. Set graph data, appearance and filters in the new Gephi Lite instance:
await Promise.all([
driver.setAppearance(appearance),
driver.setFilters(filters),
driver.setGraphDataset(dataset),
]);
// 4. Now that everything went fine, just destroy the driver (and close the
// Broacast Channel listener on this side):
driver.destroy();
}
The code has been slightly redacted from its original version:
- Some code related to the internal logic of Gephi Lite has been removed for simplicity
- Comments have been added to clarify what it does
Then, this function is called in two different parts:
- For the
"Duplicate in a new tab"
feature - For the Louvain edges ambiguity representation
How it works under the hood
This section is quite advanced, and is not necessary to use the driver. It's mostly here so that future maintainers can get more insights on what's going on in the codebase.
The BroadcastChannel
API
So, basically, the BroadcastChannel
allows for browser pages to broadcast messages on a "channel" (each channel being identified with a given string), that every other browser contexts opened in the same browser and on the same domain at the time can receive.
What Gephi Lite does
When Gephi Lite starts, it checks if it has a broadcast
query param (the channel name). If it has, it opens a BroadcastChannel
on that channel name, and listens to all messages. It will react to GephiLiteMethodBroadcastMessage
messages, that basically contain:
- a method name
- arguments for that method
- an optional identifier (that will be used for responses)
When Gephi Lite receives such a message, it will execute the asked method, and, if an identifier is given, will broadcast the return of the method on the channel, in a ReplyMessage
.
What the driver does
The @gephi/gephi-lite-broadcast
package is mostly some sugar to avoid having to write the messages by hand. Also, it waits for a reply from the related Gephi Lite instance before resolving some promise, which helps to know whether things went well, basically.
So, when some method from the driver is called, for instance const graph = await driver.getGraph();
, here is what happens:
- The driver calls its internal method:
this.callMethod<GetGraphMethod>("getGraph")
and returns a new result promise - It creates a unique
messageID
and emits aMethodBroadcastMessage
, usingthis.channel.postMessage({ ... })
- It then waits for a
MethodReplyMessage
message from the Gephi Lite instance - If the reply comes, it resolves the result promise with the reply's payload
- If it doesn't (after some
timeout
), it rejects the result promise with a timeout error
Implementing a new method for the driver
There are still some missing methods from the Gephi Lite driver, unfortunately. Here is a quick guide (mostly for maintainers) on how to implement a new method:
- A new "Method type", extending
BaseMethod
must be added inbroadcast/src/types.ts
, and added to theGephiLiteMethod
andGephiLiteMethodBroadcastMessage
union types. This will determine the arguments and response types of the new method. - A new "shortcut method" must be added directly to the
GephiLiteDriver
class. This will help TypeScript users discover this new method. It also can deal with serializing/deserializing inputs/outputs. - Finally, the actual code that tells Gephi Lite how it should handle these events must be added in the
BROADCAST_METHODS
collection, under theBaseMethod
's name. Hopefully, at this point, the typings will ensure the inputs and outputs are properly handled.
Et voilà! That's all it takes to implement a new Gephi Lite driver method.