-
Notifications
You must be signed in to change notification settings - Fork 13
MUGL Normalization Rules
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.
-
Set default values for all unspecified attributes on all tags, where the default attribute value is a fixed constant.
-
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). -
If a
<variable>tag does not specify an id, assign it anidof '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. -
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
missingvalueandmissingopattribute values from<data><variables>by<data><variables><variable>tagsIf a
<data><variables><variable>tag does not have a value for itsmissingvalueormissingopattribute, 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 themissingvalueormissingopattribute, that value remains unspecified. In other words, there is no default value for themissingvalueormissingopattributes 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. -
If a MUGL file does not contain any
<horizontalaxis>tags, insert one. -
If a MUGL file does not contain any
<verticalaxis>tags, insert one. -
If any of the
<horizontalaxis>tags in a MUGL file do not specifyidattributes, assign default ids by usingxfor the first horizontal axis,x1for the second,x2for the third, and so on. Choose the defaultidbased 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 anidattribute, but the second one does not, assign the second one anidof 'x1', not 'x'.Similarly for
<verticalaxis>, with namesy,y1,y2, etc. -
If a
<horizontalaxis>or<verticalaxis>tag does not have a<title>subtag, insert one, using the axis'sidattribute as the text of the title. For example,<horizontalaxis id="x"/>would become
<horizontalaxis id="x"> <title>x</title> </horizontalaxis> -
If a
<horizontalaxis>or<verticalaxis>tag does not have a<labels>subtag, insert one. -
If a
<labels>subtag of a<horizontalaxis>or<verticalaxis>tag does not have aspacingattribute, and if it also does not contain any<label>subtags, give it aspacingattribute value of10000 5000 2000 1000 500 200 100 50 20 10 5 2 1 0.1 0.01 0.001if the axis type is
number, or a value of1000Y 500Y 200Y 100Y 50Y 20Y 10Y 5Y 2Y 1Y 6M 3M 2M 1M 7D 3D 2D 1D 12H 6H 3H 2H 1Hif the axis type is
datetime.If a
<labels>subtag of a<horizontalaxis>or<verticalaxis>tag does not have aspacingattribute but does have one or more<label>subtags, do not provide a defaultspacingattribute value to the<labels>tag. -
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 itsspacingattribute. 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> -
Any attribute present on an axis's
<labels>tag, with the exception of aspacingattribute, 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> -
If an axis
<labels><label>tag is missing itsformatattribute (and noformatvalue is present on the containing<labels>tag), give the<label>tag aformatattribute value which is "%f" if the type of the containing axis isnumber, or "%Y-%M-%D %H:%i" if type of the containing axis isdatetime. -
The
<labels><label>and the<title>subtags of the<horizontalaxis>and<verticalaxis>tags have default values for theiranchorandpositionattributes that depend on the value of the axis'sbaseattribute. The axis'sbaseattribute 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 defaultanchorandpositionattribute values for both axis labels and titles depends on whether the axis'sbasepoint 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
positionandanchorattributes of the<labels><label>and<title>tags, in terms of the axis'sbasecoordinates. 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"/> } } -
If a
<*axis><labels><label>tag is missing itsstartattribute (and none is inherited from the containing<labels>tag), assign astartattribute value which is the result of the expressionDataValue.parse(type, "0")where
typeis the DataValue type of the containing axis. This expression returns aNumberValueobject iftypeisDataValue.NUMBER, or aDatetimeValueobject iftypeisDataValue.DATETIME.Note that this means that in terms of the MUGL XML file, the default value for the
startattribute 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 thestartattribute depends on the containing axis type. -
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> -
If a MUGL file contains no
<plot>tag, create one. -
If a
<plot>tag does not contain a<horizontalaxis>subtag, create one. -
If a
<plot>tag does not contain a<verticaxis>subtag, create one. -
If a
<plot><horizontalaxis>does not contain arefattribute, create one whose value is theidof the first<horizontalaxis>in the MUGL file. -
If a
<plot><verticalaxis>does not contain arefattribute, create one whose value is theidof the first<verticalaxis>in the MUGL file. -
If a
<plot>tag does not contain a<renderer>subtag, create one having atype="line"attribute value and no<option>subtags. -
If a
<plot><horizontalaxis>does not contain any<variable>tags, insert one whoserefattribute is the value of theidattribute 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> -
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. Therefattributes 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>