Chapter 4. Input and Output

Table of Contents

GraphML Extensions of yFiles Products
Working with the GraphML File Format
GraphML Compatibility Modes
GraphML Default Extension Mechanism
Customizing the GraphML Extension Mechanism
Customizing the yFiles FLEX I/O Support
IXmlWriter
Using Simple Data Types
Support for Structured Data
Support for Custom Serializers and Deserializers
General Serializer and Deserializer Concepts
Reading and Writing Custom Styles
Reflection Based Serialization
Server Side Reflection Based Serializer and Deserializer
Optimizing GraphML I/O
Transferring Only Structural and Layout Information
Enabling Client-Side Compression
Enabling HTTP Compression
Printing
Using CanvasComponent's Printing Support
Advanced Printing using CanvasPrinter
Customized Printing using Flex printing support
File Handling
Class SaveHandler
Configuring SaveHandler
Subclassing SaveHandler
Class LoadHandler
Configuring LoadHandler
Class ImageSaveHandler
Class ExportOptions
Subclassing ImageSaveHandler

The native exchange format of all yFiles products (yFiles FLEX, yFiles.NET, yFiles for Java) is the XML-based GraphML standard.

The GraphML file format results from the joint effort of the graph drawing community to define a common, XML-based format for exchanging graph structure data.

This chapter presents the GraphML graph exchange file format that is supported with yFiles FLEX and explains which classes to use for reading and writing graph structure and style information.

GraphML Extensions of yFiles Products

The default elements defined by the GraphML standard allow to specify only the structural information of diagrams. However, all graph item elements in a GraphML file contain a nested <data> tag that can be used to extend the GraphML data with application-dependent graphical information for graph items.

Using the <data> XML element, graphical data for nodes, edges and ports can be read and written. However, GraphML provides no direct support for further visual aspects like, e.g., zoom level, selection state, or a background image.

Since yFiles Java and yFiles.NET use different architectures for graph visualization, the XML format that is used for storing graphical information in the GraphML format differs. However, the yFiles FLEX client and yFiles.NET are using the same architecure. Therefore, yFiles FLEX and the yFiles.NET library also use the same GraphML extension for writing visual properties of graph items.

An abbreviated excerpt of a GraphML file that shows the encoding of a graph is presented in Example 4.1, “Abbreviated yFiles.NET/yFiles FLEX GraphML representation” and Example 4.2, “Abbreviated yFiles Java GraphML representation”. The basic graph structure is encoded using the GraphML elements <graph>, <node>, <edge>, and <port>. Except the latter, each of these elements has an XML attribute id whose value is used to uniquely identify graphs, nodes, and edges within a GraphML file.

XML attributes source and target which are part of the <edge> element, reference unique node IDs to indicate both source and target node of an edge. Also part of the <edge> element are XML attributes sourceport and targetport which name the respective ports that an edge connects to.

Both examples also show the extension of the GraphML format that is used by yFiles FLEX/yFiles.NET and yFiles Java, respectively, to describe the visual representation of the graph. The elements that define graphical properties of nodes, edges and ports are nested in the corresponding <data> sections.

Example 4.1. Abbreviated yFiles.NET/yFiles FLEX GraphML representation

<graphml xmlns="http://graphml.graphdrawing.org/xmlns/graphml" 
	xmlns:y="http://www.yworks.com/xml/graphml" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <key id="d0" for="node" attr.name="style" attr.type="complex"/>
  <key id="d1" for="node" attr.name="labels" attr.type="complex"/>
  <key id="d2" for="node" attr.name="geometry" attr.type="complex"/>
  <key id="d3" for="port" attr.name="style" attr.type="complex"/>
  <key id="d4" for="port" attr.name="geometry" attr.type="complex"/>
  <key id="d5" for="edge" attr.name="style" attr.type="complex"/>
  <key id="d6" for="edge" attr.name="labels" attr.type="complex"/>
  <key id="d7" for="edge" attr.name="geometry" attr.type="complex"/>
  <key id="d8" for="graphml"/>
  <graph edgedefault="directed" id="G">
    <node id="n0">
      <data key="d0">
        <y:IShapeNodeStyle>
          <y:Shape>Rectangle</y:Shape>
          <y:Pen name="SolidColor" color="#9900ff00" width="4"/>
          <y:Brush name="SolidBrush" color="#99ff0000"/>
        </y:IShapeNodeStyle>
      </data>
      <data key="d1">
        <y:Labels>
          <y:Label>
            <y:ISimpleLabelStyle>
              <y:Font family="Serif" points="40" style="Italic,Underline"/>
              <y:Brush name="SolidBrush" color="#ff000000"/>
              <y:Background>
                <y:Brush name="SolidBrush" color="#99ffff00"/>
                <y:Pen name="SolidColor" color="#9900ffff" width="1"/>
              </y:Background>
            </y:ISimpleLabelStyle>
            <y:ExteriorLabelModel position="West">
              <y:ModelState>
                <y:Insets left="10" right="60" top="10" bottom="30"/>
              </y:ModelState>
            </y:ExteriorLabelModel>
            <y:Text>n1L1</y:Text>
            <y:PreferredSize width="82" height="47"/>
          </y:Label>
        </y:Labels>
      </data>
      <data key="d2">
        <y:Geometry x="5" y="5" width="30" height="30"/>
      </data>
      <port name="p0">
        <data key="d3"/>
        <data key="d4">
          <y:Geometry x="0" y="0"/>
        </data>
      </port>
    </node>
    <node id="n1">
      <data key="d0">
        <y:IGeneralPathNodeStyle>
          <y:GeneralPath>
            <y:MoveTo x="0" y="0"/>
            <y:LineTo x="0" y="1"/>
            <y:QuadTo cx="0.2" cy="0.2" x="1" y="1"/>
            <y:LineTo x="1" y="0"/>
            <y:Close/>
          </y:GeneralPath>
          <y:Pen name="SolidColor" color="#7fffcc00" width="2"/>
          <y:Brush name="SolidBrush" color="#4cff0000"/>
        </y:IGeneralPathNodeStyle>
      </data>
      <data key="d1">
        <y:Labels>
          <y:Label>
            <y:ISimpleLabelStyle>
              <y:Font family="Serif" points="40" style="Italic,Underline"/>
              <y:Brush name="SolidBrush" color="#ff000000"/>
            </y:ISimpleLabelStyle>
            <y:InteriorLabelModel position="SouthWest">
              <y:ModelState>
                <y:Insets left="0" right="0" top="0" bottom="0"/>
              </y:ModelState>
            </y:InteriorLabelModel>
            <y:Text>n2L1</y:Text>
            <y:PreferredSize width="82" height="47"/>
          </y:Label>
        </y:Labels>
      </data>
      <data key="d2">
        <y:Geometry x="100" y="100" width="100" height="60"/>
      </data>
      <port name="p0">
        <data key="d3"/>
        <data key="d4">
          <y:Geometry x="0" y="0"/>
        </data>
      </port>
    </node>
    <node id="n2">
      <data key="d0">
        <y:ImageNodeStyle>
          <y:Image url="http://www.yworks.com/tmp/flex/logo.gif"/>
        </y:ImageNodeStyle>
      </data>
      <data key="d1"/>
      <data key="d2">
        <y:Geometry x="-15" y="85" width="30" height="30"/>
      </data>
    </node>
    <edge id="e0" source="n0" target="n1" sourceport="p0" targetport="p0">
      <data key="d5">
        <y:IPolylineEdgeStyle>
          <y:Pen name="SolidColor" color="#990000ff" width="2"/>
          <y:Arrow at="source" type="Spearhead" cropLength="5">
            <y:Pen name="SolidColor" color="#99ff0000" width="2"/>
            <y:Brush name="SolidBrush" color="#99ffcc00"/>
          </y:Arrow>
          <y:Arrow at="target" type="Default" cropLength="0">
            <y:Pen name="SolidColor" color="#ff000000" width="1"/>
            <y:Brush name="SolidBrush" color="#ff000000"/>
          </y:Arrow>
        </y:IPolylineEdgeStyle>
      </data>
      <data key="d6">
        <y:Labels>
          <y:Label>
            <y:ISimpleLabelStyle>
              <y:Font family="Serif" points="12" style="Regular"/>
              <y:Brush name="SolidBrush" color="#ff000000"/>
            </y:ISimpleLabelStyle>
            <y:RotatingEdgeLabelModel ratio="0.6">
              <y:ModelState angle="1.8"/>
            </y:RotatingEdgeLabelModel>
            <y:Text>e1l1</y:Text>
            <y:PreferredSize width="20" height="15"/>
          </y:Label>
        </y:Labels>
      </data>
      <data key="d7">
        <y:Path/>
      </data>
    </edge>
  </graph>
  <data key="d8"/>
</graphml>

Example 4.2. Abbreviated yFiles Java GraphML representation

<?xml version="1.0" encoding="UTF-8"?>
<!-- This file was written by the JAVA GraphML Library. -->
<graphml xmlns="http://graphml.graphdrawing.org/xmlns/graphml" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns/graphml 
  http://www.yworks.com/xml/schema/graphml/1.0/ygraphml.xsd" 
  xmlns:y="http://www.yworks.com/xml/graphml">
  <key id="d0" for="node" yfiles.type="nodegraphics"/>
  <key id="d1" for="edge" yfiles.type="edgegraphics"/>
  <graph id="G" edgedefault="directed">
    <node id="n0">
      <data key="d0">
        <y:ShapeNode>
          <y:Geometry x="170.5" y="-15.0" width="59.0" height="30.0"/>
          <y:Fill color="#CCCCFF" transparent="false"/>
          <y:BorderStyle type="line" width="1.0" color="#000000"/>
          <y:NodeLabel>January</y:NodeLabel>
          <y:Shape type="rectangle"/>
        </y:ShapeNode>
      </data>
    </node>
    <node id="n1"/>
    <edge id="e1" source="n1" target="n0">
      <data key="d1">
        <y:PolyLineEdge>
          <y:Path sx="0.0" sy="-15.0" tx="29.5" ty="0.0">
            <y:Point x="425.0" y="0.0"/>
          </y:Path>
          <y:LineStyle type="line" width="1.0" color="#000000"/>
          <y:Arrows source="none" target="standard"/>
          <y:EdgeLabel>Happy New Year!</y:EdgeLabel>
          <y:BendStyle smoothed="false"/>
        </y:PolyLineEdge>
      </data>
    </edge>
  </graph>
</graphml>

The GraphML file format is also described in the GraphML Primer.

More information about working with the yFiles GraphML extensions and yFiles FLEX interoperability with the two extension formats can be found in Chapter 6, Using yFiles FLEX with a yFiles Server.