A Guide to Diagram – Part 2 – Content for Nodes

In the last article I demonstrated how we could create a simple data model with three nodes and some links between them.  However, the end result was less than impressive from a visual perspective:

Our diagram do far


In this article I'll explore what you can actually do to the nodes to create something that is visually more attractive, and which conveys a little more information.
The idea of course is to add further ADF components inside of the diagramNodes to include more information and maybe images as well. 
However, you can't use every ADF component inside a node, there is a restricted subset of components that you can use (See the <dvt:diagramNode> tagdoc).  Importantly, don't expect to use any input components on the nodes.  If you need to "edit" the content of a node then you'll have to use popups launched from the node in question to do so.

The Basic Components

The following components are officially supported within a node:
  • af:button / commandButton / goButton
  • af:image
  • af:link / commandLink / commandImageLink / goLink
  • af:outputText / outputFormatted
  • dvt:marker / pointLocation 
And the following layout components:
  • af:panelFormLayout
  • af:panelGroupLayout
  • af:panelLabelAndMessage
  • af:spacer
  • af:separator
  • f:facet
  • dvt:panelCard / af:showDetailItem
And behaviors:
  • dvt:drillBehavior
  • dvt:isolateBehavior
  • dvt:restoreBehavior
  • dvt:rowDisclosureBehavior
  • af:showPopupBehavior

Of course any popup referenced by showPopupBehavior references content outside of the diagram and so any popups can contain the full range of ADF and DVT components.

What you need to be aware of 

When ADF components are rendered inside of a diagram node they are not output to the browser in the normal way.  Instead, they are transformed into the corresponding SVG elements within the diagram.  One result of this transformation is that any style classes applied to the component using the styleClass attribute will be ignored.  However, all is not lost! The framework will support a subset of CSS style directives directly defined in the inlineStyle attribute for the component. The CSS that is supported in this way includes background and border styling and font information.  You should be aware, however, that any style directive that involves sizing is not going to be respected in absolute terms as the nodes on the diagram will be scaled depending on the zoom level. 

You'll also note that there is no support for <af:clientListener> and <af:clientAttribute> within a node.  When components are rendered on a diagram node they do not currently support any client side manipulation and do not expose a client API to JavaScript in the browser. 

As well as the standard layouts and output components that you will be more than familiar with, diagram can also use some extra components that may be less familiar; panelCard and marker.

PanelCards

PanelCards (<dvt:panelCard>) were first introduced with the Hierarchy Viewer component, and provide a way of defining a series of "cards", defined by af:showDetailItem tags, which are arranged in a logical ring inside of the panel.  The user is able to move from card to card using the navigation breadcrumbs or button as shown:  

`First of two cards within a panelCard component Second of two cards within a panelCard component

In the above example there are two <af:showDetail> components, the first displaying phone number and email, and the second the address.

You can define an animation used for the transition between cards using the effect attribute which supports various sliding and rotating animations:

  • immediate - no transition effect
  • slide_horz - old content slides out on one side while new content slides in from the other side
  • flip_horz - the showDetailItem flips over to reveal new contents
  • node_flip_horz - the whole node flips over to reveal new contents 

Markers

 Another supported child of the diagramNode that you may not be familiar with already is the marker.  Markers are already used with other DVT components such as maps, and specifically in cases where a scaling shape component is needed.  There are several pre-defined shapes for marker:
  • Circle
  • Square
  • Rounded rectangle
  • Diamond
  • Plus sign
  • Upwards facing triangle
  • Downwards facing triangle
  • Human figure
The look of these standard shapes can be controlled in terms of sizing of course, plus fill and line colors, gradients, opacity and rotation. So they make for very flexible "primitives" to represent either entire nodes or node overlays (as we'll see shortly).  However, as well as the built-in shapes you can provide your own marker shapes in the form of images provided as .png, .jpeg etc. or for clean scaling during zoom, as SVG images.  Markers can themselves also have a label attribute, if required, so often it's sufficient to use a marker as the sole content of your diagram node.
Here's an improved version of my simple diagram, from part 2 in this series, where I've updated the bare <dvt:diagramNode> definition to now use a marker to represent the node:

...
<dvt:diagramNode id="dn1" nodeId="#{node.uniqueNodeId}" label="#{node.nodeLabel}">
  <f:facet name="zoom100">
    <dvt:marker shape="circle"
                height="20" width="20"
                fillColor="#ff0000" borderColor="#000000" 
                borderStyle="solid" borderWidth="1.0"/>
  </f:facet>
</dvt:diagramNode>
...

And here's the visual result of that simple change 

Updated diagram with markers

 I think that you can see that the diagram is instantly more useful!

Node Facets

Like many other JSF components, the diagramNode supports a variety of facets, you can divide these up into three groups; general facets, zoom facets and container facets. 
For now I'll ignore the container facets, I'll look at those in a later article when I cover containers and grouping, but you'll encounter the first two categories early on. 

Zoom Facets

The concept of zoom facets may be familiar to you if you've used hierarchy viewer in the past. The point here is that although diagram can successfully scale content as the user zooms in and out, there is a point where the information present on a node is unreadable because it becomes too small.  Zoom facets give you four content buckets (zoom100, zoom75, zoom50, zoom25) in which you can include different sets of components.  Thus at the zoom100 level you might define a complex layout using a panelcard and images and generally pack in all the contact information for an employee.  However on the zoom25 facet you might just include the picture of the employee, therefore using the available space to it's best advantage when the node area is tiny.  As the user zooms in an out each of these zoom facts will be selected appropriately to best fit the contents of the node automatically.  You will always have a zoom100 facet defined, however, the others are optional. 

General Facets

The Label Facet

The label facet provides you with an opportunity to define specific styling for the node label.  As such, it replaces (and overrides) the label attribute of the <dvt:diagramNode> itself. Generally you'd use this facet to alter the styling of the label, but you can also use it to achieve useful things such as creating a multi-line label,. You would do this  by including a vertical panelGroupLayout within the label facet and creating each line of the label with a separate <af:outputText>. You can even include other components such as images, links and buttons in this facet should you desire.

The Background Facet

As the name suggests the background of the node can be set with the content of this facet. As such <af:image> and <dvt:marker> tags can be used here to provide an image.  The actual content of the Zoom facets will be overlaid on top of this background.  The contents of this facet will be zoomed with the node as the user manipulates the diagram, therefore for optimum quality it's best to use <dvt:marker> with an SVG image as the source here.

Here's an example where I'm using an SVG in the background facet and normal text in the zoom100 facet, plus a label (PDB1) on the <dvt:diagramNode> itself:

Use of a background marker

Note that a <dvt:marker> tag used as a background is purely visual and any action or actionListener defined on it will be ignored.  The image that you supply in the background facet will be automatically be sized to fit the actual contents of the nodes, so choose images here that are well matched to the contents of the node or unwanted things may happen.  For example, if I'm careless and don't round my free space percentage in my outputText in this diagram node -  this would happen - so be careful: 

Node background being stretched by it's content

Here's the code for this node as a reference:

<dvt:diagramNode id="dn1" nodeId="#{node.uniqueNodeId}" label="#{node.dbName">
  <f:facet name="zoom100">
    <af:panelGroupLayout layout="vertical" halign="center"
                         inlineStyle="height:40px;margin-top:20px;margin-left:5px;margin-right:5px;">
      <af:outputText value="Free Space"/>
      <af:outputText value="#{node.freeSpace}"/>
    </af:panelGroupLayout>
  </f:facet>
  <f:facet name="background">
    <dvt:marker source="/images/database.svg"/>
  </f:facet>
</dvt:diagramNode> 

The reality is that you will not use the background facet that much, using the Zoom facets is better to achieve the same end, until you start to use containers and node grouping.  Then background becomes useful, as we shall see in a later article. 

The Overlay Facet

The overlay facet is an extremely useful feature.  It expects one or more <dvt:marker> tags as children, and these markers, as the facet name suggests, overlaid on top of the node contents. 

Here's an example of the previous example (correctly sized!) with an overlay indicating that the 12c pluggable database represented by the node is up. 

Diagram Node with a single overlay

Here's the overlay facet definition that created that:

<f:facet name="overlay">
  <af:group>
    <dvt:pointLocation pointX="100%" pointY="0%">
      <dvt:marker shape="triangleUp" fillColor="#00ff00" borderColor="#00a500" borderStyle="solid" height="16" width="16"/>
    </dvt:pointLocation>
  </af:group>
</f:facet>
You'll notice here that a new tag has been introduced - <dvt:pointLocation>.  This tag allows us to position the marker either in absolute, or more normally, in percentage terms, relative to the top left corner of the node (at 0,0). Note that you can specify percentage values that are greater than 100% or that are negative. This will to allow you to offset the markers as required left, right, up and down, from the body of the node. 

The overlay facet can also support multiple markers within the overlay group, so by adding different pointLocations we can apply "badges" to different parts of the node, like this:

Diagram node with two overlay markers

<f:facet name="overlay">
  <af:group>
    <dvt:pointLocation pointX="100%" pointY="0%">
       <dvt:marker shape="triangleUp" fillColor="#00ff00" 
                   borderColor="#00a500" borderStyle="solid"
                   height="16" width="16"/>
    </dvt:pointLocation>
    <dvt:pointLocation pointX="100%" pointY="90%">
       <dvt:marker source="/images/info.svg"
                   height="16" width="16"/>
    </dvt:pointLocation>
  </af:group>
</f:facet> 

As well as being visual indicators, the markers can also add functionality, specifically you can define action, actionListener and destination(url) properties to use it to invoke navigation or code execution.  Additionally you can define a <af:showPopupBehavior> tag as a child of the marker to invoke a popup when the marker is clicked.

The final consideration with all of these general facets (label, background and overlay) is that they are present no matter what the zoom level, they do not support  different definitions at the 100, 75, 50 and 25% levels.

But What if I Have Different Types of Node?

Within a diagram node you can do all of the usual tricks with expression language to display different values, use different images and even switch components on and off with the rendered property.  However, if you have several distinct types of nodes you may actually want to define separate <dvt:diagramNode> components within the diagram tag. This will help to keep your code easier to read and is very common with more complex diagrams where you may need to define different properties to different classes of nodes.
You can control which diagramNode definition is used to display a particular member of the nodes collection using the rendered property on  the <dvt:diagramNode> component itself.  For example, if you look at the Simple Rules Editor demo for diagram you will see multiple node definitions, each of which uses an expression like this to control which definition handles which node definition:
  rendered="#{node.ruleNodeType eq 'CONDITION'}"
So in this case, this node defintion will be used when the node type evaluates to the String value "CONDITION".

Guidelines for Node Design

Diagrams are a very effective way of conveying many types of data, but they excel at being able to help users visualize a large number of complex connections within large data sets.  Diagram has been designed to scale to handle these large datasets and is more than capable of displaying of hundreds of nodes and links. However, when designing your diagram you want to keep several factors in mind, to optimize the user experience and responsiveness:
  1. Keep the contents of your nodes simple.  Rather that overloading your diagram with large amounts of text, you may find that simple images may be much easier for the user to understand when trying to take in the entirety of the diagram.  You can then use drilldown to provide access to more detailed information if it is required.
  2. Use the zoom facets.  If you are including detailed content in each node then be sure to define relevant levels of detail at each zoom level so the content of the nodes remains readable and usable.
  3. If using an image to represent a node then seriously consider using an SVG image format. SVG images will scale much more gracefully as the user zooms in and out. 
  4. Don't display all of the data at once.  Features such as containership which we'll cover in a later article can help to hide some of the complexity of the diagram, allowing the user to drill down into more detail as required.   You can also investigate using an intermediate or wrapper model that filters the full data model, limiting the number of nodes that need to be displayed at any one time. 

In the Next Article

 Now that we understand a little about formatting nodes and their contents, the next article will complete the picture and talk about links. 


Comments:

Post a Comment:
  • HTML Syntax: NOT allowed
About

Oracle Data Visualizations provide a broad range of beautiful, interactive components for viewing and understanding data. This blog covers topics on the new features in Oracle Data Visualization components and how-to articles on advanced functionality.

Search

Categories
Archives
« August 2015
SunMonTueWedThuFriSat
      
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
25
26
27
28
29
30
31
     
Today