i2 Notebook SDK
Search results for

    Show/hide table of contents

    Creating a plug-in that changes the colors of nodes

    This tutorial takes you through writing a plug-in for the i2 Notebook web client that can change the color of nodes on a chart.

    You can find a full version of the source code for this tutorial in the samples/color-plugin folder.

    Prerequisites

    This tutorial requires a running instance of i2 Analyze on which you have permission to use the i2 Notebook web client.

    To follow the tutorial, you must install at least version 12 of Node.js on your development machine. For downloads and more information about Node.js, visit the project website at https://nodejs.org.

    The tutorial also requires you to create GUIDs for a number of its elements. The project files use some sample fixed GUIDs (00000000-0000-0000-0000-000000000001, 00000000-0000-0000-0000-000000000002, and so on), but you should always create real GUIDs for real projects.

    Note: A suitable GUID generator is available online at https://www.guidgenerator.com.

    Create a plug-in

    To arrive at the starting point for this tutorial, follow the instructions in the Creating a production-ready plug-in tutorial, up to but not including the section named Add a ribbon command to the plug-in.

    These instructions initialize the plug-in and provide a foundation for development. Once the setup is complete, you will have a basic structure ready for further customization.

    Set up the SDK version

    The minimum API version to run this tutorial is 1.9.

    Ensure that your project has the correct version of the SDK installed. In package.json, verify or update the dependency to ensure the requested API version is 1.9 or later:

    {
      "dependencies": {
        "@i2analyze/notebook-sdk": "^1.9.0"
      }
    }
    

    After updating your dependencies, modify the entrypoint.ts file to request the correct API version:

    const api = await notebook.getEntryPointApi('00000000-0000-0000-0000-000000000001', '1.9');
    

    You may experience an error in entrypoint.ts that asks you to install npm i --save-dev @types/node and add "types": ["node"] to the tsconfig.json. Do not worry about this as we will be amending this code in the next tutorial step.

    Add a ribbon command

    Using the plug-in infrastructure created for us, we'll add a new command to the ribbon that will eventually change the color of nodes that contain vehicle records to the colors of those vehicles.

    1. In entrypoint.ts, replace the existing createCommand() call with the following:

      const colorVehicleNodes = api.commands.createCommand({
        id: '00000000-0000-0000-0000-000000000002',
        name: 'Color vehicle nodes',
        type: 'application',
        icon: {
          type: 'inlineSvg',
          svg: commandSvg,
        },
        onExecute() {},
      });
      
      const homeTab = api.commands.applicationRibbon.homeTab;
      const chartManagementCommand = homeTab.systemGroups.chartManagement;
      
      homeTab.after(chartManagementCommand).surfaceCommands(colorVehicleNodes);
      
    2. This will create a command called 'Color vehicle nodes' and surface the command under the Home tab.

    Set node colors

    To set the color of a node, we'll use a mutation (see Supported mutation operations) that requires the NodeSpecifier of the node, and the color to change the node to.

    In the sections that follow, we will:

    1. Find all records of the vehicle entity type on the chart.
    2. Retrieve the color of the vehicle from each vehicle record.
    3. Set each vehicle record's node element to the color of the vehicle.

    Find all vehicle records on the chart

    Elements on the chart surface are defined by and contain records that store data (see Record data). We can gain access to the chart and all the entity records via the argument of type app.IApplicationContents passed to the onExecute() event handler.

    To determine whether a record has a particular type, we need to specify which type we're looking for! We'll look up the entity type by its display name from the chart's schema object (see Schema data).

    1. Access the chart schema through the onExecute() application contents parameter, and get the vehicle entity type by its display name.

    2. Access all of the chart entityRecords through the onExecute() application contents parameter.

    3. Find the records with the vehicle item type.

    4. If there are no vehicle records, just return.

      onExecute(applicationContents) {
         const vehicleItemType = applicationContents.chart.schema.entityTypes.get("Vehicle");
      
         if (!vehicleItemType) {
           return;
         }
      
         const allEntityRecords = applicationContents.chart.entityRecords;
      
         const vehicleRecords = allEntityRecords.filter(
           (record) => record.itemType === vehicleItemType
         );
      },
      ...
      

    At this point, we now have all the vehicle type entity records, and we're ready to retrieve the color property for each record.

    Retrieve a color from each vehicle record

    We will now find the color for each vehicle. Instead of accessing the item types in the schema, we'll need to access the property types in the vehicle item type.

    1. Use the vehicleItemType object to get the vehicle color property type via the property's display name.

    2. Gain access to mutations by calling api.runTrackedMutations() and setting a handler function.

    3. Inside the mutation handler, loop over every vehicle entity record.

    4. Use the color property type to retrieve the color of the vehicle that the record represents.

      const colorPropertyType = vehicleItemType.propertyTypes.get('Vehicle Color');
      
       if (!colorPropertyType) {
         throw new Error('Color property type not found for vehicle item type');
       }
      
      api.runTrackedMutations((_, mutations) => {
        for (const vehicleRecord of vehicleRecords) {
          const vehicleColor = vehicleRecord.getProperty(colorPropertyType);
          ...
      

    Set the record's element to the color of the vehicle

    Finally, for each vehicle record we found, we'll use a mutation to set the color of the node element that contains it to the color of the vehicle.

    1. Retrieve the record's containing element using the element property.

    2. Use the mutations parameter to call the editNode() method, and then the setColor() method.

    3. Return an ITrackedMutationCommit object from the runTrackedMutations() method call.

      ...
      api.runTrackedMutations((_, mutations) => {
        for (const vehicleRecord of vehicleRecords) {
          const vehicleColor = vehicleRecord.getProperty(colorPropertyType);
      
          const vehicleElement = vehicleRecord.element;
          mutations.editNode(vehicleElement.id).setColor(vehicleColor?.toString());
        }
      
        return {
          type: 'commit',
          actionDisplayName: 'Set vehicle node colors',
        };
      });
      ...
      

    Note: This implementation assumes that the vehicle color value in the record property is in a format that the setColor() method supports.

    Now, if a chart contains one or more nodes with a vehicle record, clicking the ribbon button changes the color of all those nodes to their vehicle color.

    In this article
    Back to top © N. Harris Computer Corporation