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 structured (overloaded) relation that represents tabular data as a table, if it’s supported by the client.

The input is expected to be a relation that represents a table column-wise, such as the result of importing a CSV file, or i.e. a module. The module provided as input can be thought of like a dataframe in other systems. The client will attempt to display a table from whatever module you pass in, even if the data is sparse, or not all of the same arity.

Includes the original relation together with a MIME-type indicating the relation represents a table, in order to be rendered on the client.

Input

  • R: an overloaded relation of the following form: R[:ColName][keys...](value)

Examples

Displaying a loaded CSV:

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

Displaying a table module constructed from several column-relations:

table[{
    (:Name , name) ;
    (:Team , team) ;
    (:EmployeeId , employeeid) ;
}]

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
    }