Skip to content

MUGL Normalization Rules

frimmel edited this page Oct 23, 2012 · 27 revisions

In order to allow for convenient authoring of MUGL files, the MUGL specification allows certain tags and attributes to be omitted, and Multigraph will assume that those tags/attributes have certain default values. In many cases, the default values are simply constants; for example, the default color for an axis is black. In some cases, though, default values need to be computed based on the context; for example, the default format for axis labels depends on the data type of the axis.

We say that a MUGL file is "normalized" if it contains values for all tags and attributes that Multigraph needs, with no need to compute any additional defaults. This page lists the rules used to "normalize" a MUGL file. These rules are written here in no particular order, with the understanding that some of them will trigger other ones; for example a rule that insert a <horizontalaxis> tag will trigger rules regarding default attributes and subtags of that <horizontalaxis> tag. The process of normalizing a MUGL file consists of repeatedly transforming the MUGL file by applying rules from this list, until the MUGL file reaches a state where no rules in the list apply to it.

These rules can also be interpreted as applying to object instances in Multigraph, in which case, generally speaking, tags correspond to objects, and attributes correspond to object properties. In some cases there is not a one-to-one correspondence, however. For example, in a MUGL file a <data> tag contains a <variables> subtag which contains one or more <variable> subtags. In terms of Multigraph objects, though, the <data> tag corresponds to an instance of a (submodel of the) Data model, and each <variable> tag corresponds to an instance of the DataVariable model in the Data model's data collection; there is no object instance corresponding directly to the <variables> tag. The rules on this page are worded in terms of MUGL xml tag and attribute values; when they are interpreted in the context of object instances, they should be interpreted in a way that results in the same object instances and property values that would have resulted if the corresponding normalized MUGL file had been given to Multigraph in the first place.

  • Constant Defaults

    Set default values for all unspecified attributes on all tags, where the default attribute value is a fixed constant.

  • Missing data.variables

    If a <data> tag does not have a <variables> tag but does have a <values> tag, examine the first row of values in the <values> tag to determine the number of variables (columns) present, and create a <variables> tag with one <variable> tag for each variable. If a <data> tag does not have a <variables> tag and also does not have a <values> tag, throw an error (we insist on <variables> tags for both <csv> and <service> data objects).

  • Default data.variables.variable id attribute

    If a <variable> tag does not specify an id, assign it an id of 'x' for a variable in column 0, 'y' for a variable in column 1, 'y1' for a variable in column 2, 'y2' for a variable in column 3, and so on. These default ids should be chosen based strictly on the column number, regardless on which variables in the data tag have explicitly specified ids. So, for example, if we have

         <data>
          <variables>
            <variable column="0" type="datetime" id="time"/>
          </variables>
          <values>
            20120602, 13.1
          </values>
        </data>
    

    Then we would insert

            <variable column="1" type="number" id="y"/>
    

    after the first <variable> tag.

  • Default data.variables.variable column attribute

    If a <variable> tag in a <data><variables> tag is missing its column attribute, assign a default based on its order in the list of <variable> tags in that tag, starting with 0, but skipping any column numbers that are explicitly specified. For example, the normalized form for

        <variables>
          <variable type="number" id="foo" column="1"/>
          <variable type="number" id="bar"/>
          <variable type="number" id="bat"/>
        </variables>
    

    would be

        <variables>
          <variable type="number" id="foo" column="1"/>
          <variable type="number" id="bar" column="0"/>
          <variable type="number" id="bat" column="2"/>
        </variables>
    
  • Inheritance of missingvalue and missingop attribute values from <data><variables> by <data><variables><variable> tags

    If a <data><variables><variable> tag does not have a value for its missingvalue or missingop attribute, and the containing <data><variables> tag does have a value for that same attribute, the <data><variables><variable> tag should inherit that attribute value.

    If neither the <data><variables><variable> tag nor the containing <data><variables> tag specifies a value for the missingvalue or missingop attribute, that value remains unspecified. In other words, there is no default value for the missingvalue or missingop attributes of the <data><variables><variable> tag; there is only the rule that says that the value is inherited from the value of the same attribute on the containing <data><variables>, if any.

  • Missing <horizontalaxis> tag

    If a MUGL file does not contain any <horizontalaxis> tags, insert one.

  • Missing <verticalaxis> tag

    If a MUGL file does not contain any <verticalaxis> tags, insert one.

  • Default axis id attributes

    If any of the <horizontalaxis> tags in a MUGL file do not specify id attributes, assign default ids by using x for the first horizontal axis, x1 for the second, x2 for the third, and so on. Choose the default id based strictly on where the axis is in the sequence of horizontal axes in the MUGL file; e.g. if the first horizontal axis in the file has an id attribute, but the second one does not, assign the second one an id of 'x1', not 'x'.

    Similarly for <verticalaxis>, with names y, y1, y2, etc.

  • Missing <*axis><title> tag

    If a <horizontalaxis> or <verticalaxis> tag does not have a <title> subtag, insert one, using the axis's id attribute as the text of the title. For example,

      <horizontalaxis id="x"/>
    

    would become

      <horizontalaxis id="x">
        <title>x</title>
      </horizontalaxis>
    
  • Missing <*axis><labels> tag

    If a <horizontalaxis> or <verticalaxis> tag does not have a <labels> subtag, insert one.

  • Missing <*axis><labels> spacing tag

    If a <labels> subtag of a <horizontalaxis> or <verticalaxis> tag does not have a spacing attribute, and if it also does not contain any <label> subtags, give it a spacing attribute value of

      10000 5000 2000 1000 500 200 100 50 20 10 5 2 1 0.1 0.01 0.001
    

    if the axis type is number, or a value of

      1000Y 500Y 200Y 100Y 50Y 20Y 10Y 5Y 2Y 1Y 6M 3M 2M 1M 7D 3D 2D 1D 12H 6H 3H 2H 1H
    

    if the axis type is datetime.

    If a <labels> subtag of a <horizontalaxis> or <verticalaxis> tag does not have a spacing attribute but does have one or more <label> subtags, do not provide a default spacing attribute value to the <labels> tag.

  • Missing <*axis><labels><label> tags

    If a <labels> subtag of a <horizontalaxis> or <verticalaxis> tag does not have any <label> subtags, give it one <label> subtag for each space-separated value in the value of its spacing attribute. For example,

        <horizontalaxis id="x" type="number">
          <labels spacing="10 5 2 1" format="%1d"/>
        <horizontalaxis>
    

    would become

        <horizontalaxis id="x" type="number">
          <labels spacing="10 5 2 1" format="%1d">
            <label spacing="10" format="%1d">
            <label spacing="5" format="%1d">
            <label spacing="2" format="%1d">
            <label spacing="1" format="%1d">
          </labels>
        <horizontalaxis>
    
  • Inheritance of <*axis><labels> attribute values by child <label> tags

    Any attribute present on an axis's <labels> tag, with the exception of a spacing attribute, should be propagated down to any containing <label> tags (including ones inserted by other rules in this list) that do not contain their own setting for that attribute. For example,

        <horizontalaxis id="x" type="number">
          <labels format="%2d" angle="45">
            <label spacing="10">
            <label spacing="5">
            <label spacing="2" format="%1d">
            <label spacing="1" format="%1d">
          </labels>
        <horizontalaxis>
    

    would become

        <horizontalaxis id="x" type="number">
          <labels format="%2d" angle="45">
            <label spacing="10" format="%2d" angle="45">
            <label spacing="5" format="%2d" angle="45">
            <label spacing="2" format="%1d" angle="45">
            <label spacing="1" format="%1d" angle="45">
          </labels>
        <horizontalaxis>
    
  • Default value for <*axis><labels><label> format attribute

    If an axis <labels><label> tag is missing its format attribute (and no format value is present on the containing <labels> tag), give the <label> tag a format attribute value which is "%f" if the type of the containing axis is number, or "%Y-%M-%D %H:%i" if type of the containing axis is datetime.

  • Default value for anchor and position attributes of <*axis><labels><label> and <*axis><title>tags

    The <labels><label> and the <title> subtags of the <horizontalaxis> and <verticalaxis> tags have default values for their anchor and position attributes that depend on the value of the axis's base attribute. The axis's base attribute value is a 2-dimensional point in a rectangular coordinate system going from (-1,-1) to (1,1) that represents the graph's plot area or padding area. The default anchor and position attribute values for both axis labels and titles depends on whether the axis's base point is in the top or bottom half (for horizontal axes) or the left or right half (for vertical axes) of this coordinate system.

    The following pseudo-code gives the default values that should be used for the position and anchor attributes of the <labels><label> and <title> tags, in terms of the axis's base coordinates. This logic is only used to set default values for attributes that do not have values in the original MUGL file (or, in the case of the <label> tag, values inherited from the containing <labels> tag).

      if (axis is horizontal) {
        if (-1 <= base.y < 0) {
          // axis is in the bottom half of the graph
          <label position="0 -5"/>
          <label anchor="0 1"/>
          <title position="0 -18"/>
          <title anchor="0 1"/>
        } else {
          // axis is in the top half of the graph
          <label position="0 5"/>
          <label anchor="0 -1"/>
          <title position="0 15"/>
          <title anchor="0 -1"/>
        }
      }
      if (axis is vertical) {
        if (-1 <= base.x < 0) {
          // axis is in the left half of the graph
          <label position="-8 0"/>
          <label anchor="1 0"/>
          <title position="-25 0"/>
          <title anchor="1 0"/>
        } else {
          // axis is in the right half of the graph
          <label position="5 0"/>
          <label anchor="-1 0"/>
          <title position="33 0"/>
          <title anchor="-1 0"/>
        }
      }
    
  • Default value for <horizontalaxis><labels><label> start attribute

    If a <*axis><labels><label> tag is missing its start attribute (and none is inherited from the containing <labels> tag), assign a start attribute value which is the result of the expression

      DataValue.parse(type, "0")
    

    where type is the DataValue type of the containing axis. This expression returns a NumberValue object if type is DataValue.NUMBER, or a DatetimeValue object if type is DataValue.DATETIME.

    Note that this means that in terms of the MUGL XML file, the default value for the start attribute is always the constant "0". So this rule is a no-op in the context of transforming the MUGL XML string or structure. But in the context of transforming instantiated objects inside the Multigraph code, the default value of the start attribute depends on the containing axis type.

  • Multiple values in <*axis><labels><label> spacing attribute

    If an axis's <labels><label> tag's spacing attribute is a string containing multiple values separated by whitespace, replace that <label> tag with multiple label tags, one for each spacing value. For example,

        <horizontalaxis id="time" type="datetime">
           <labels>
             <label spacing="10Y 5Y 2Y 1Y" format="%Y"/>
             <label spacing="5M 2M 1M" format="%M %Y"/>
           </labels>
        <horizontalaxis>
    

    would become

        <horizontalaxis id="time" type="datetime">
           <labels>
             <label spacing="10Y" format="%Y"/>
             <label spacing="5Y" format="%Y"/>
             <label spacing="2Y" format="%Y"/>
             <label spacing="1Y" format="%Y"/>
             <label spacing="5M" format="%M %Y"/>
             <label spacing="2M" format="%M %Y"/>
             <label spacing="1M" format="%M %Y"/>
           </labels>
        <horizontalaxis>
    
  • Missing <plot> tag

    If a MUGL file contains no <plot> tag, create one.

  • Missing <plot><horizontalaxis> tag

    If a <plot> tag does not contain a <horizontalaxis> subtag, create one.

  • Missing <plot><verticalaxis> tag

    If a <plot> tag does not contain a <verticaxis> subtag, create one.

  • Missing <plot><horizontalaxis> ref attribute

    If a <plot><horizontalaxis> does not contain a ref attribute, create one whose value is the id of the first <horizontalaxis> in the MUGL file.

  • Missing <plot><verticalaxis> ref attribute

    If a <plot><verticalaxis> does not contain a ref attribute, create one whose value is the id of the first <verticalaxis> in the MUGL file.

  • Missing <plot><renderer> tag

    If a <plot> tag does not contain a <renderer> subtag, create one having a type="line" attribute value and no <option> subtags.

  • Missing <plot><horizontalaxis><variable> tag

    If a <plot><horizontalaxis> does not contain any <variable> tags, insert one whose ref attribute is the value of the id attribute of the first <variable> of the MUGL file's first <data> tag. For example,

      <mugl>
        <plot>
          <renderer type="line"/>
        </plot>
        <data>
          <variables>
            <variable column="0" id="x"/>
            <variable column="1" id="y"/>
          </variables>
        </data>
      </mugl>
    

    would become

      <mugl>
        <plot>
          <horizontalaxis>
            <variable ref="x"/>
          </horizontalaxis>
          <renderer type="line"/>
        </plot>
        <data>
          <variables>
            <variable column="0" id="x"/>
            <variable column="1" id="y"/>
          </variables>
        </data>
      </mugl>
    
  • Missing <plot><verticalaxis><variable> tag

    If a <plot><verticalaxis> does not contain any <variable> subtags, insert a number of <variable> subtags into the <plot><verticalaxis> tag equal to the dimension of that <plot>'s renderer: a 1-variable renderer (such as "line", "bar", "fill", etc) would receive one <variable> subtag, a 2-variable renderer (such as "band", "rangebar", etc) would receive two <variable> subtags, etc. The ref attributes of the inserted <variable> subtags should be set to the ids of variables in the first data section, starting with the second variable in that section.

      <mugl>
        <plot>
          <renderer type="line"/>
        </plot>
        <data>
          <variables>
            <variable column="0" id="x"/>
            <variable column="1" id="y"/>
          </variables>
        </data>
      </mugl>
    

    would become

      <mugl>
        <plot>
          <horizontalaxis>
            <variable ref="x"/>
          </horizontalaxis>
          <verticalaxis>
            <variable ref="y"/>
          </verticalaxis>
        </plot>
        <data>
          <variables>
            <variable column="0" id="x"/>
            <variable column="1" id="y"/>
          <renderer type="line"/>
          </variables>
        </data>
      </mugl>