4.5. Two-Way Data Manipulation

The previous example, Section 4.4, “Modifying Data”, showed how to modify data from a source point to a destination point. But what if you need to modify data bidirectionally—such as keeping two readings of Celsius/Fahrenheit temperature data in synch? You can quickly set up a script for two-way data manipulation like this:

  1. Open the Properties window, select the Scripting option, and click the New button to create a new script.
  2. In the New Script File dialog, name the main class 'MyXform' and select the Allow only one instance and Bridging options. More details.
  3. Click OK and the script window will open, loaded with the newly-created script. If you'd like you can now add the file to your list of files in the Properties window. Here's how.
  4. When you run the script the Data Browser will open, along with an Instructions dialog:
  5. Click OK and open the Data Browser if it isn't open already:
    In the default domain, you should see two new points: Celsius and Fahrenheit.
  6. Click on point name Celsius and in the Enter new value: field, enter a new value. You should see the value for Fahrenheit change accordingly. Change the value of Fahrenheit, and Celsius will change as well.

This is an example of bi-directional linear transformation between two points. It is based on the LinearXform class, which is defined in the LinearXForm.g script that comes with your DataHub distribution. The class gets instantiated by the code in the script you just created and are now running. Here are the main parts of your MyXform.gscript, with a bit of commentary:

class MyXform Application
{
    xform = new LinearXform ();
}

The LinearXform gets instantiated as an instance variable of the MyXform class.

/* This method configures all of the bridging transformation for this example.
   To add more bridging transformations, simply copy and modify the line
   starting with .xform.AddLinearXform. */
method MyXform.bridgeconfig ()
{
    .xform.verbose = t;
    .xform.AddLinearXform (self, #$default:Celsius, #$default:Fahrenheit, 9/5, 32, t);
}

As the comment suggests, here you can add points with transformation arguments. The syntax is explained below. All that is left to do now is construct the class. The constructor calls .bridgeconfig to build the data transformation bridges, and then sets initial values, opens the Data Browser, and displays the usage instructions:

method MyXform.constructor ()
{
    /* Create the transformations */
    .bridgeconfig();

    /* Set initial values */
    $default:Fahrenheit = 32;

    /* Display the data view window */
    datahub_command ("(show_data 1)", 1);

    /* Give instructions to the user */
    MessageBox (0, "Open the data browser and alter the values for 
default:Celsius and default:Fahrenheit to see an automatic
computation when a value changes.", "Instructions", 0);
}

4.5.1. Adapt it for your needs

This code can easily be adapted to do any two-way linear transformation between two points. Just add lines to the .bridgeconfig method to meet your needs. Here is the syntax:

.xform.AddLinearXform (self, #$domain:source, #$domain:target, multiplier, adder, bidirectional);

The arguments you need to specify are:

domain:source

The domain and name of the data point that is the source of the data. Remember, the # symbol prevents evaluation, and the $ escapes the colon (:) between the domain and point name. Also, you will need to use a forward slash (\) to escape blank spaces in a point name. Windows allows blank spaces in point names, but you have to escape them in DataHub scripts.

domain:target

The domain and name of the data point that is the target of the data.

multiplier

A multiplier (m) for the linear transformation, such as in the equation: y = mx + b

adder

An adder (b) for the linear transformation, such as in the equation: y = mx + b

bidirectional

Indicates whether the data can be written from either direction. Use t for yes, or nil for no. These are the only two values that may be used.

For example, for currency exchange you could add this line to the .bridgeconfig method:

.xform.AddLinearXform (self, #$default:euros, #$default:dollars, .82, 0, t);

To set dollars to 100, add this line to the .constructor method:

$default:dollars = 100;