Skip to content

Displaying time from a controller

Introduction

In this tutorial we'll create a view with an SVG that displays the current time in a controller. You won't have to edit the code in the controller or reload it since we're using standard system functions.

Note

The view and SVG can be downloaded from here but you will still need to follow some of the setup steps for it to work.

Setup

  • In InteractiveSVGs, create a new User Area called ControllerTime.
  • Open Folder Views Tool and remove all the default Widgets and Link Icons.
  • Create a new Link Icon and leave the default name as is (UnnamedLinkIcon_1).
    • Change the (Global) Controller argument to a controller that exists in your project

In the File attribute, select Create a new view in this user area..., change the name to ControllerTime.Rwav and save the the changes in Folder Views Tool.

Open the newly created view for editing.

  • Remove the default elements.
  • Add a Symbol element with the name ControllerTimeSvg.
    • Set the attribute Pictures to Area:\ControllerTime.svg.
    • Set the attribute Appearance/Style to SVG animation.
  • Save the file.
  • Open the area folder (Ctrl+F8).
  • Create a new file called ControllerTime.svg.

Note

In your browser, if you navigate to the new User Area, you will not see anything (besides some errors in the console) since we haven't added any content to the SVG yet.

Adding the bindings

Select the ControllerTimeSvg element and paste the following code into the Value attribute. Make sure to save the view when done:

ControllerTimeSvg.Value
{ 
  // Instead of just specifing a simple binding
  // expression (*%Controller%.Variable) we return
  // an object with multiple bindings.
  //
  // Note that you must enclose the code with
  // curly brackets/braces ({}) to make this
  // type of binding work.
  const object = { 
    hour:   *%Controller%.QSystem.Hour,
    minute: *%Controller%.QSystem.Minute,
    second: *%Controller%.QSystem.Sec
  }

  return object; 
}

Adding the SVG content

Open ControllerTime.svg in your favorite editor and paste the following code. Make sure to save the file when done:

ControllerTime.svg
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink"
     viewBox="0 0 300 300">

  <!-- The text element where the current time is rendered -->
  <text id="currentTime" x="20" y="20" />

  <script id="controllerTime" type="application/javascript">
    //<![CDATA[
      // The element variable is provided by the Arrigo Web runtime.
      // It has a htmlElement property which we use to get a reference
      // to the svg itself (so we can reference the elements within it).
      const svg = element.htmlElement.querySelector('svg');

      // Grab a reference to the text element using its id.
      const currentTime = svg.querySelector('#currentTime');

      // Every Interactive SVG must define a init(evt) function.
      // init(evt) is invoked by the Arrigo Web runtime when
      // everything is good to go, so use this is the main entry point
      // for setting up all the things you need in your SVG.
      function init(evt) {
        console.log("ControllerTime.svg is about to initialize");
      }

      function renderTime(hour, minute, second) {
        // Add a leading zero if needed using a 
        // template literal (template string).
        if (hour < 10) hour = `0${hour}`;
        if (minute < 10) minute = `0${minute}`;
        if (second < 10) second = `0${second}`;

        // Glue the parts together and set is as 
        // a new value for the text element.
        currentTime.textContent = `${hour}:${minute}:${second}`;
      }

      // Every Interactive SVG must define a onChanged function.
      // attributeName - The name of the attribute that changed.
      //                 Usually 'width', 'height' or 'value'.
      // value - The new value.
      const onChanged = function(attributeName, value) {
        // Switch on the attribute name.
        // We're only interested in the 'value' attribute.
        switch (attributeName) {
          case "value":
            // Remember that we returned an object from
            // ControllerTimeSvg.Value?
            // That is the object we're provided with here,
            // so we must access the individual properties
            // of that object and pass them into renderTime().
            renderTime(value.hour, value.minute, value.second);
            break;
        }
      }
    //]]>
  </script>
</svg>

The result

Open your browser and navigate to the area. The first time your view loads it should look like this:

The current time

Wait a couple of seconds and verify that the time ticks on:

Time ticks on

Quick review

In this part we bound to multiple variables in a controller and returned them as an object. Remember that you must check which attribute is being updated in onChanged!

Ideas and improvements

Just like in the previous tutorial, this svg could be extended to include the current date in the rendering.