Added two new stroke-related properties as inheritable styles: strokeCap and strokeJoin. These expose the stroke endcap and join styles which, prior to this change, were always "butt-ended" and "mitered join", respectively.
Changed the values of three of the "synonyms" for the strokePat attribute: dashed = "30 30" instead of "99 50"; dashdot = "30 30 10 30" instead of "99 50 10 50"; and dashdotdot = "30 30 10 30 10 30" instead of "99 50 10 50 10 50".
(22 Mar 2010, app v3.4.0) Added optional color attribute cmapnan to the zaxis ("color axis") element. This specifies the opaque RGB color to which any ill-defined datum (NaN or infinity) is mapped when rendering a heatmap in the parent graph. This "NaN color" replaces the entry at index 0 of the selected color map (cmap), so ill-defined data are mapped to colormap index 0, while well-defined data are mapped to the index range [1..255]. In prior versions, in the onscreen rendering of a heatmap, an ill-defined datum was mapped to a transparent pixel, but this was never implemented in the Postscript rendering. Rather than support transparency in Postscript (LL3 required), we decided to make the onscreen rendering opaque. Note that this change did not require a new schema version.
(07 May 2010, app v3.4.2) Added boolean attribute smooth to the heatmap element. Prior to v3.4.2, smooth interpolation of the heatmap image was always enabled, but some users didn't want it because it can be misleading -- suggesting a smoothness in the underlying data that does not exist. This attribute was added so that users can now turn off smoothing. Since the attribute is optional, it was not necessary to increment the schema version upon making this change. If the attribute is not explicitly specified -- as will be the case for all existing schema 10 documents prior to this change -- it defaults to true.
(09 Jun 2010, app v3.4.4) Added two additional options, jet and reversejet, to the enumerated attribute cmap of the zaxis element.
(08 Dec 2010, app v3.5.4) Added boolean attribute avg to the raster element. Prior to this change, the histogram display of a raster node reflected the total counts per bin across the raster collection (avg == false, the default). Now, if avg== true, the histogram reflects the average counts per bin (total divided by the number of individual rasters in the raster collection).
One new element, zaxis, representing the third dimension in a graph. It is a required component of a graph node, and it must be the third element listed in the graph's element content. It controls the color-mapping properties that determine how any and all heatmaps are rendered in a graph. Formerly, the heatmap element itself had an attribute (cmap) that selected one of six possible color maps. Now it gets all color-mapping information from the parent graph's Z axis: the color map itself, the mapped data range (start and end attributes), and the mapping mode (the new cmode attribute). All heatmaps in a single graph are now rendered using the same color-mapping properties. As with the primary and secondary axes, the zaxis may be rendered; the rendering includes a gradient bar depicting the content of the color map, alongside the typical axis line with optional tick sets that depict the data range spanned in this "Z" dimension. The zaxis has all the same attributes an axis node except the units attribute; additional attributes include the cmap and cmode properties, plus gap (distance between gradient bar and nearest edge of graph window), size (gradient bar width), and edge (the graph window edge alongside which the Z axis is drawn).
Removed cmap attribute from the heatmap element.
In schema version 7, the axis element was modified so that it no longer restricted the number of tick set children it could contain. However, schemas 7 and 8 still enforced the upper limit of 4 tick sets, established in schema version 0. The restriction is relaxed in this version.
Added four new adornment types for the cap attribute of calib and ebar nodes, or the type attribute on shape and symbol nodes: dart, reversedart, kite, and reversekite.
This schema version coincides with the initial release of Figure Composer. Versioning began at 3.0 to avoid overlap with Phyplot version numbers. There were significant changes and additions to the FypML schema with this release:
Two new data presentation nodes were added, raster and heatmap. These are specialized for the rendering of two new data set formats, described below. Introduced new attributes in support of these elements: nbins, cmap.
The storage and structure of datasets changed substantially:
Two new dataset formats were added: raster1d is a collection of 0 or more x-coordinate vectors, or rasters (typically used to store spike trains collected over multiple presentations of the same stimulus); and xyzimg is a 3D dataset in which one variable Z is a function of two independent variables X and Y. Z(X,Y) is "sampled" over the rectangle [x0..x1, y0..y1] in the XY-plane. It can be thought of as an image, and it is in fact rendered as such via a color lookup table in the heatmap element.
The series and mseries formats now include -- in addition to the sample interval dx -- a second parameter x0 specifying the x-coordinate for the first sample in the series.
The figure model entity encapsulating data sets was entirely rewritten for Figure Composer. In Phyplot, the "raw data" was a list of double-precision floating-point tuples which could (but usually didn't) have different lengths. Now, the raw data is generally interpreted as a matrix with a fixed number of rows (data "breadth") and columns (data "length") packed row-wise into a single-precision floating-point array. In addition, the data set entity is an immutable object.
The figure model no longer manages a "data store" as in schema versions 6 and 7. "Orphaned" data sets are no longer possible. Now, a data presentation element (trace, raster, or heatmap) stores a reference to the data set it uses, and such references can be shared because the data set object is immutable.
The definition of the set element changed substantially to support this new way of representing data sets. By far the biggest change was to store the raw data as base64-encoded binary. This decision sacrifices the flexibility to read or write a valid FypML figure file using a simple text editor or a homespun script. But it provides a form that is much more precise (full single-precision float VS a numeric string with up to 6 decimal digits), compact, and opaque. The last two are important considerations given that data sets and figure models will eventually need to be transported over the Internet if we incorporate FypML figures in a future data portal application.
The set element supports both the old "comma-separated tuples" and the new base64-encoded text content. This simplifies migration and puts off the task of parsing the old-style tuples until the data set entity is actually created (more efficient and easier than trying to parse the old-style tuples and converting them directly to the base64-encoded binary form). During migration a new attribute, v7, is explicitly set to true on each existing set element, which is otherwise left unchanged. The presence of this attribute informs the XML-to-model converter to expect the schema 7 version of the set element.
FypML places additional restrictions on the identifier of a data set: (1) maximum length of 40 characters; (2) Only ASCII alphanumeric characters and selected punctuation marks $ _ [ ] ( ) { } + - ^ ! = are allowed. During schema migration, the id attributes of schema version 7 set elements are altered as necessary to meet these criteria. Of course, the src attribute of each trace element that references the set with the corrected id is likewise corrected.
This schema version corresponds with a major re-design of the entire Phyplot application. There were extensive changes to the FypML schema, although no changes in the element namespace:
The graph element now requires a legend child as the fifth child node. During migration, the legend node is added to any graph that lacks it, with its hide attribute set to true.
The axis element no longer admits any label or line elements as children. If any are encountered during migration, they are simply removed. This should not be an issue, since such usage was extremely rare. (As of v2.0.2) During migration, if the axis has an empty title attribute and at least one label child with a non-empty title attribute, that title becomes the title attribute value for the axis. (As of v2.1.0) Any number of ticks elements are admitted as children of an axis, instead of a maximum of 4.
The legend node no longer has strokeWidth or strokeColor attributes; they were never used.
Eliminated the notion of "document-level default" attribute values. In the prior schema version, the attributes cap, capSize, mid, spacer, labelOffset, perLogIntv, dir, len, fmt, and gap had default values specified on the figure node; they were required attributes for the figure. During migration, the old document-level defaults are explicitly set on the relevant nodes as Phyplot traverses the node tree.
The font attribute only specifies a single font family instead of two.
The fontSize attribute is no longer a Measure attribute type (e.g., "12pt" or "0.2in"), but an integer in [1..99] specifying the font size in typographical points. The old font size is converted to points, rounded to nearest integer, and range-restricted.
The substfont attribute is now called altFont, and it is defined on any element that has font-related properties. Like all graphic styles, it is inheritable. Also, the altFont choice sans-serif is replaced by sanserif.
The psfont attribute is now psFont (note the capital 'F').
The strokePat attribute replaces lineType, with some important differences. Each dash-gap length is now restricted to [1..99] and is measured in 0.1 line-widths instead of milli-inches. In addition, the hidden line style on longer exists. Finally, strokePat is treated as inheritable property just as strokeWidth is; it is defined on the container classes figure and graph even though a Phyplot author will always set strokePat=solid for such elements.
New attribute legend replaces the hide attribute on function and trace nodes. During migration, if hide=false, then legend=true (meaning, include an entry for the data presentation element in the parent graph's legend).
The type attribute on a trace node is now mode; its usage is unchanged.
The horiz attribute on a calib node is now primary; its usage is unchanged.
The value none is no longer recognized as a valid adornment type for the cap attribute of calib and ebar nodes, or the type attribute on shape and symbol nodes. To achieve the same effect, the attribute specifying adornment size (capSize or size) is set to 0in. In addition, adornment type names are now all in lowercase letters (eg, fillThinArrow is now fillthinarrow), and the colon (':') has been removed from all type names that had it (eg, oval1:2 is now oval12).
The synonyms all, even and none for the perLogIntv attribute have been dropped.
Most of the allowed values for the fmt attribute of a set element have changed in spelling: pointSet is now ptset, multiSet is now mset, and multiSeries is now mseries.
The old pointSet, multiSet, and series elements have been replaced by a single trace node, a presentation element which defines how a referenced data set is rendered in a graph. The trace element's type attribute defines its display mode; four display modes are supported: polyline mode, in which the data points are connected by a polyline, possibly adorned with marker symbols and/or error bars; multitrace mode, in which a collection of polylines represents individual data sets, with another polyline tracing the average across those sets; errorband mode, in which polylines are drawn for the nominal trace, +1STD, and -1STD, with the band between the two standard-deviation polylines optionally filled with a solid color; and histogram mode, in which the data set is rendered as a histogram, possibly (but rarely) adorned with marker symbols and error bars. The trace element has most of the attributes of the old series element, with some exceptions and a few additions. The dx attribute is gone -- this is considered an attribute of the data itself, not its presentation. The x0 attribute is now called xoff and is accompanied by a new yoff attribute, allowing the user to apply arbitrary x- and y-offsets to the referenced data. The data set itself is now stored separately (see below), and referenced by the trace element's new src attribute.
Separation of data storage from data presentation. The root figure node now contains a single mandatory ref node, which is always its last child. The ref element has no attributes; it merely serves as a container for any number of set nodes. This is where "locally stored data sets" are kept in the Phyplot document. [Eventually, Phyplot will support remote data sources -- hence the term "local" to refer to data stored within the document itself.] As before, the data is stored in the text content of the set node as a comma-separated list of datum tuples, where each such tuple is a whitespace-separated list of one or more floating-point numbers. Additional info about the set is specified in three attributes. The required id attribute is a non-empty string with no whitespace that serves as an identifier for the data set: a trace element references a local set with id=myset by setting its src attribute to #myset. The fmt attribute indicates the data set format -- pointset, series, multiset, or multiseries. The pointset format corresponds directly to the now-obsolete pointSet element, where each tuple is a list of 2-6 numbers: x y [yStd ye xStd xe]. The series format corresponds directly to the old series element, where each tuple is a list of 1-3 numbers: y [yStd ye]. The multiset format is a more general version of the old multiSet element's format. Here each tuple is a list of 2 or more floating-point numbers: x y1 [y2 y3 ...]. All tuples should have the same length, but if that is not the case, the minimum tuple length determines the number of individual sets in the collection (the extra numbers in the longer tuples are simply ignored). Note that, for generality's sake, the format permits a collection that defines only a single point set! Finally, the multiseries format is new -- it is essentially a sampled multiset. Each tuple is a list of 1 or more floating-point numbers: y1 [y2 y3 ...]. For the two sampled formats, the set element's optional dx attribute indicates the sample interval for the x-coordinate; its implicit value is 1.
The function element no longer has the skip attribute. It was superfluous since the dx can really serve the same purpose. During migration, if a function element is encountered with skip !=1, then the element's dx attribute is simply adjusted to the value dx = dxOld*skipOld.