Skip to content
  • REL
  • REFERENCE
  • Libraries
  • display

The Visualization Library (display)

Visualization tools including text, table, and figures. See also: the vega and vegalite libraries.

graphviz

graphviz[G]

Visualize the provided relation G as a graph, using Graphviz, if supported by the client.

Input

  • G: A module containing the following:

    • :node: a unary relation of identifiers (usually strings or integers) to use as node ids.
    • :edge: a binary relation of edges as (from, to) pairs of node ids.
    • :node_attribute: a ternary relation of node attributes as (node_id, attribute,

    value), where node_id matches an identifier in the :node relation. Here, attribute must be a string; it cannot be a RelName.

    • :edge_attribute: an arity-4 relation of edge attributes as (from, to, attribute,

    value), where (from, to) matches an identifier pair in the :edge relation.

Here, attribute must be a string; it cannot be a RelName.

  • :attribute:graph: a binary relation of graph attributes as (attribute, value).

These attributes serve as the default for the graph/subgraphs.

  • :attribute:node: a binary relation of node attributes as (attribute, value).

These attributes serve as the default for all nodes in the graph.

  • :attribute:edge: a binary relation of edge attributes as (attribute, value).

These attributes serve as the default for all edge in the graph.

  • :subgraph: a relation with an identifier followed by a graph definition (:node,

:edge, :attribute, :node_attribute, :edge_attribute) with the following exceptions: - :directed is not supported as that applies to the whole graph and not a subgraph - :clustered is not supported as that applies to the whole graph and not a subgraph. If you want to only have a subset of the subgraphs be clusters, set the root key :clustered to boolean_false and prepend "cluster_" to the subgraph IDs you would like to be clusters. - :subgraph cannot be recursively defined - :parent can be added to subgraphs with the value set to the ID of another subgraph. This indicates that this subgraph should nested within that parent subgraph.

  • :directed: a boolean (boolean_true or boolean_false) indicating whether the graph is directed or undirected. Defaults to true (directed).

  • :clustered: a boolean (boolean_true or boolean_false) indicating whether the subgraphs in the graph should have their IDs prepended with cluster_ so that the subgraphs are each rendered in a bounding box. Defaults to true (clustered).

  • :layout: a string indicating the layout engine to use. Valid options are:

    • "circo"
    • "dot" (default)
    • "fdp"
    • "neato"
    • "osage"
    • "patchwork"
    • "twopi"
  • :width: the width of the visualization in pixels. Defaults to the width of the container.

  • :height: the height of the visualization in pixels. Defaults to 500 pixels.

All configuration options are optional. However, a valid graph G must define at least :node or :edge .

See the Graphviz documentation for the full list of supported attributes and values.

Examples

Simple graph

def node = {"A"; "B"; "C"}
def edge = {"A", "B"; "A", "C"}
def graph = {:node, node; :edge, edge}
 
def output = graphviz[graph]

Outputs a directed graph with the nodes "A", "B", and "C" with edges between "A" and "B", as well as "A" and "C".

Complex graph

def nodes = {"grandparent"}
 
def node_attrs = {
  "grandparent", "fontname", "Comic Sans MS"
}
 
def edges = {
  "grandparent", "parent A";
  "grandparent", "parent B";
}
 
def edge_attrs = {"grandparent", "parent A", "color", "blue"}
 
def attribute:graph = {
  "bgcolor", "lightblue"
}
def attribute:node = {"color", "charcoal"; "fontname", "Impact"}
def attribute:edge = {"color", "grey"}
 
def subgraphs = {
  "parents",  {
    :node, {"parent A"; "parent B"};
    :edge, "parent B", "child";
    :attribute, :node, {"color", "lightgrey"; "style", "filled"};
    :attribute, :graph, "bgcolor", "white";
  };
  "children",  {
    :parent, "parents";
    :node, "child";
    :node_attribute, "child", {"color", "red"};
  };
}
 
def graph = {
  :node, nodes;
  :edge, edges;
  :directed, boolean_false;
  :node_attribute, node_attrs;
  :edge_attribute, edge_attrs;
  :attribute, attribute;
  :subgraph, subgraphs;
}
 
def output = graphviz[graph]

Outputs an undirected graph with the nodes "grandparent", "parent A", "parent B", and "child", which has a light blue background, nodes outlined in charcoal with “Impact” font, and grey edges by default.

The "grandparent" node uses "Comic Sans MS" as its font instead of "Impact"

The edge from "grandparent" to "parent A" is blue instead of grey.

The nodes "parent A", "parent B", and "child" are all drawn within a white background bounding box. The nodes within this subgraph are lightgrey and filled, overwriting the graph’s default. Within that box, "child" is also in a bounding box and is red instead of lightgrey.

Definition

@inline
def graphviz[G] = {
    :MIME, MIME_GRAPHVIZ;
    :graph, :data, G;
}
 
@inline
def MIME_GRAPHVIZ = "application/vnd.rel.relation.graph.graphviz"

help

help[:relation_name]

Display the docstring for a relation relation_name, by richly rendering it as Markdown.

This is equivalent to markdown[docstring[:relation_name]].

Example

def output = help[:sum]

Displays the markdown-formatted docstring for load_csv as richly-rendered HTML in the frontend UI, if it is supported by the client.

See Also:

  • markdown[R]
  • docstring[:relation_name]

Definition

@inline
def help[relation_name] = markdown[docstring[relation_name]]

html

html[R]

Display the provided relation R as an html document, if supported by the client.

Includes only the tuples from ‘R’ where the last value is a String, together with the “text/html” MIME-type, to be displayed as an HTML document in the client. The relation can have any arity and cardinality.

Example

def output = html["<h1>Hello, World</h1>"]

Outputs the HTML mime type along with the “Hello, World” HTML string.

def output = html[{:key1, "<p>more info</p>"; :key2, "<br/>"; :a_number, 1}]

Outputs the HTML mime type along with the “more info” and break HTML strings (order not guaranteed), but not the number 1 as that tuple does not have a String as its last value.

Definition

@inline
def html[R] = {
        :MIME, MIME_HTML;
        :text, :html, ks..., str
    }
    from ks..., str where R(ks..., str) and String(str)
 
@inline
def MIME_HTML = "text/html"

markdown

markdown[R]

Display the provided relation R as markdown formatted text, if supported by the client.

Includes only the String-valued tuples from R, together with the “text/markdown” MIME-type, to be displayed as a Markdown value in the client.

Example

def output = markdown[docstring[:load_csv]]

Definition

@inline
def markdown[R] = {
        :MIME, MIME_MARKDOWN;
        :text, :markdown, ks..., str
    }
    from ks..., str where R(ks..., str) and String(str)
 
@inline
def MIME_MARKDOWN = "text/markdown"

svg

svg[R]

Display the provided relation R as an svg image, if supported by the client.

Includes only the tuples from ‘R’ where the last value is a String, together with the “image/svg+xml” MIME-type, to be displayed as an svg image in the client. The relation can have any arity and cardinality.

Example

def output = svg["<svg height=100 width=100><circle r=100 cx=100 cy=100 fill='blue' /></svg>"]

Outputs the SVG mime type along with the blue circle SVG string.

def output = svg[{
    :circle, "<svg height=100 width=100><circle r=100 cx=100 cy=100 fill='blue' /></svg>";
    :square, "<svg height=100 width=100><rect width=100 height=100 /></svg>";
    :a_number, 1
  }]

Outputs the SVG mime type along with the blue circle and rectangle SVG strings (order not guaranteed), but not the number 1 as that tuple does not have a String as its last value.

Definition

@inline
def svg[R] = {
        :MIME, MIME_SVG;
        :image, :svg, ks..., str
    }
    from ks..., str where R(ks..., str) and String(str)
 
@inline
def MIME_SVG = "image/svg+xml"

table

table[R]

Display a relation R as a table if supported by the client.

Parameters

VariableTypeDescription
RRelationA relation that stores tabular data in the form (column_name, row_key..., value).

Explanation

Expects a relation in GNF format (column_name, row_key..., value) that represents a table.

To display a relation as a table with multiple columns, a shared key row_key... is needed to correlate the data into rows. The row identifier row_key... as the ... indicates can be a composite key that contains multiple values. In this case, the last argument in R is always interpreted as the value in the table cell.

Expected format is similar to dataframes used by other systems.

Can be used, for example, to display the result of importing a CSV file.

Output includes the original relation together with a MIME-type indicating the relation represents a table, so that it can be rendered on the client.

Relations of the form (column_name, row_key) are supported and are interpreted as (column_name, row_key, true) where the value in the table cell is true. Note that Rel follows a two-valued logic and therefore doesn’t require an explicit boolean data type. The true table cell value is not supported with composite row keys (row_key...).

Examples

Display a relation as multi-column table:

//note that numerical key coordinates `name` and `team1
def name = {(1, "Fred"); (2, "Tran"); (3, "Jane")}
def team = {(1, "Manchester United"); (2, "Chelsea"); (3, "Milan AC")}
 
def output = table[{
    ("Name", name);
    ("Team", team);
}]

Display a module as table:

module M 
    def product = {(1, "laptop"); (2, "monitor"); (3, "keyboard")}
    def inventory = {(1, 27); (2, 34); (3, 50)}
end
def output = table[M]

Display loaded CSV data:

def R = load_csv["/path/to/my_csv.csv"]
def output = table[R]

Definition

@inline def table[R] = {
        :MIME, MIME_APPLICATION_TABLE;
        :table, :data, R
    }
 
// Custom MIME type that indicates the relation should be interpreted as a Table.
@inline
def MIME_APPLICATION_TABLE = "application/vnd.rel.relation.table"

view_json

view_json[R]

Display a structured (overloaded) relation as a JSON Object, if it’s supported by the client.

To represent JSON Arrays an explicit array marker, :[], and an index specifying the position in the array are expected.

Input

  • R: an overloaded relation.

Examples

Displaying a simple JSON Object:

def data[:a] = 1
def output = view_json[data]
 
// Expected output:
// {"a": 1}

Displaying a nested Array:

def data[:a, :[], 1, :[], 1, :b] = 1
def data[:a, :[], 1, :[], 2, :c] = 2
def output = view_json[data]
 
// Expected output:
// {"a": [[{"b": 1}, {"c": 2}]]}

Displaying a cake recipe:

def document[:id] = "0001"
def document[:type] = "donut"
def document[:name] = "Cake"
def document[:ppu] = 0.55
 
def document[:batters, :batter, :[], 1, :id] = "1001"
def document[:batters, :batter, :[], 1, :type] = "Regular"
def document[:batters, :batter, :[], 2, :id] = "1002"
def document[:batters, :batter, :[], 2, :type] = "Chocolate"
def document[:batters, :batter, :[], 3, :id] = "1003"
def document[:batters, :batter, :[], 3, :type] = "Blueberry"
def document[:batters, :batter, :[], 4, :id] = "1004"
def document[:batters, :batter, :[], 4, :type] = "Devil's Food"
 
def output = view_json[document]

Definition

@inline def view_json[R] = {
        :MIME, "application/vnd.rel.relation.json";
        :json, :data, R
    }
Was this doc helpful?