Scalable vector graphics (SVG) are used for the visual representation of the blocks. This allows us to decouple the visual components from the language definition in the metamodel. This decoupling allows for easier modification and creation of new visual aspects of the language. The decoupling of the language definition and the visual aspects requires the creation of general rules for transforming a given SVG when another block is connected or nested within the given SVG component. Therefore, every dynamic SVG in the visual programming language must contain relevant information for the application of the appropriate stretching or shifting allowed by the given SVG.
SVG transformations are composed of a series of stretches and shifts applied to the individual elements of the SVG. That is, the placement of a block inside of another results in the stretching and shifting of individual elements of the parent block to visually represent the containment of the new child element. As shown below, these transformations can be rather significant.
These shifts and stretches must be specified in the svg file. Stretches are specified with respect to the name of the connection that will cause the given element to stretch and the given axis to stretch. Shifts are specified with respect to the id of the SVG element which will cause shifts to the location of the given element and the given axis to shift. That is, the SVG element will designate an element which, when stretched or shifted, will cause a stretch or shift in the given SVG element.
Each block on the screen has current stretch values organized by the connection name that is being stretched. When another block is connected to a connection area, the parent block’s stretch values for the given connection area (termed “stretch class”) are updated and will be updated on the next screen refresh. Organizing the elements into stretch classes allows the SVG elements to be stretched to the maximum of the stretches of the stretch classes to which the SVG elements belong. As the SVG element’s stretch classes’ stretches are all recorded, the size of the SVG element is easily updated on the event of a significant de- crease in the largest stretch class value. That is, if an element has three stretch classes, say “first”, “second” and “third”, with values 15, 17 and 20, respectively, the element will be stretched to 20. On the event that “third” is changed to 10, the SVG element can easily update itself to depend upon the stretch value of the new maximum, “second” (with a value of 17).
Unlike the stretching of the SVG elements, shifting is dependent upon other SVG elements rather than connection names. Given the shifting specifications in the SVG, our visualization component of WebGME will create a forest of shift trees for each of the elements of the SVG. Shifts are then applied by applying a
shift to the children of each stretched node and allowing the shifts to propogate down the tree. Connection areas designated in the SVG support the same functionality and can be added as leaves to the shift tree for the given SVG. For example, if we let eidesignate elements and cidesignate a connection area of a given SVG
such that e8,4,5have a shift dependency on e6, e1,7,3have a shift dependency on e8and c1, e10 have a shift
dependency on e3, we will create the left shift tree in Figure IV.2. Letting e2be an unshifting element with
dependents e11, e9will give us the tree on the right.
e6 e8 e4 e5 e1 e7 e3 c1 e10 e2 e9 e11
Using this constructed forest of shift trees, we can then apply shifts by first shifting the children of stretched elements by the given amount. As previously described, these shifts will then propogate down the tree to update all dependent elements. Suppose, for our example, we have the following stretches in the SVG:
e6= 12
e8= 7
e1= 11
This will update the left shift tree as follows:
e6(0)
e8(12) e4(12) e5(12)
e1(19) e7(19) e3(19)
c1(19) e10(19)
e11(30)
It is worth noting that the stretching elements and shifting elements have significantly different require- ments; this is both with respect to what the elements depend upon and how their values are calculated given their dependents. The stretching elements depend upon the values of their given stretch classes (which are determined from size of any block connected to a given connection area). Given these stretch class values, the SVG element will stretch to the max stretch value dictated by the stretch classes. The shifting elements, however, are dependent on their descendents in their given shift tree; the shift value is then given by the summation of the stretch and shift values of the parent.
CHAPTER V
Constraint Generation
Constraint generation is done in 3 major steps. First, variables are hoisted to the top of the file and declared with respect to their given data type. Next, the blocks are traversed and the code is generated from the block code templates. Finally, any dependent functions required by the code templates are prepended to the generated code.
As discussed in Chapter III, a block may have both an attribute and pointer with the same name to represent a value that can be specified by either user specified text or a relationship with another block. During compilation, any values from block relationships take precedence over any user specified text (attributes in the data model). Constraint code for a given block is generated by first finding any values that would be replaced by the attributes of the given block (such as input of text fields). Then, for any pointer name required in the template, code is generated for the target block of that given pointer. This ordering allows the information about any connected block to override any attribute value that may be inputted to the given block. This approach effectively results in a creation of the code which generates the code of children and sibling connections before the node’s code is generated. The constraint generation uses a robust, template based code generation. The use of templates allows our constraint generator to be easily extendable with the addition of new language concepts and with any future language or syntax changes. Like Scratch, the constraint code is generated only from code accessible from the main entrypoint; disconnected blocks are ignored [17].
The most novel aspect of the code generation for the visual constraint language lies in it’s ability to generate asynchronous code. Using this asynchronous code generation, the compiler enables the user to create more manageable, synchronous code using the blocks and will compile the block source code into the necessary asynchronous JavaScript code as necessary. The constraint generator also uses intelligent variable name mapping to allow the user to ignore character restrictions or reserved words restrictions in naming variables.