-
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 anid
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. -
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
andmissingop
attribute values from<data><variables>
by<data><variables><variable>
tagsIf a
<data><variables><variable>
tag does not have a value for itsmissingvalue
ormissingop
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 themissingvalue
ormissingop
attribute, that value remains unspecified. In other words, there is no default value for themissingvalue
ormissingop
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. -
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 specifyid
attributes, assign default ids by usingx
for the first horizontal axis,x1
for the second,x2
for the third, and so on. Choose the defaultid
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 anid
attribute, but the second one does not, assign the second one anid
of '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'sid
attribute 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 aspacing
attribute, and if it also does not contain any<label>
subtags, give it aspacing
attribute value of10000 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 of1000Y 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 aspacing
attribute but does have one or more<label>
subtags, do not provide a defaultspacing
attribute 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 itsspacing
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>
-
Any attribute present on an axis's
<labels>
tag, with the exception of aspacing
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>
-
If an axis
<labels><label>
tag is missing itsformat
attribute (and noformat
value is present on the containing<labels>
tag), give the<label>
tag aformat
attribute 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 theiranchor
andposition
attributes that depend on the value of the axis'sbase
attribute. The axis'sbase
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 defaultanchor
andposition
attribute values for both axis labels and titles depends on whether the axis'sbase
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
andanchor
attributes of the<labels><label>
and<title>
tags, in terms of the axis'sbase
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"/> } }
-
If a
<*axis><labels><label>
tag is missing itsstart
attribute (and none is inherited from the containing<labels>
tag), assign astart
attribute value which is the result of the expressionDataValue.parse(type, "0")
where
type
is the DataValue type of the containing axis. This expression returns aNumberValue
object iftype
isDataValue.NUMBER
, or aDatetimeValue
object iftype
isDataValue.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 thestart
attribute 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 aref
attribute, create one whose value is theid
of the first<horizontalaxis>
in the MUGL file. -
If a
<plot><verticalaxis>
does not contain aref
attribute, create one whose value is theid
of 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 whoseref
attribute is the value of theid
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>
-
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. Theref
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>