Hierarchical charts

.qp.network.format

Format a table to be in the shape expected by the graph layout algorithm

Parameters:

Name Type Description
t table Table to format
c symbol[] Pair of symbols indicating the id and child columns

Returns:

Type Description
table Formatted table

.qp.network.layout

Perform a force-directed layout on the given table

Parameters:

Name Type Description
t table Table to layout
x symbol ID column
y symbol Child column
o null | dict (decay: float; speed: long; ticks: long; c: float; maxdepth: long; theta: float) Options to control the layout

Returns:

Type Description
table Edge-table with original node properties added in

Example: Basic network


     g: .gg.cheat.i.assemble[];

     layout: .qp.network.layout[g; `id; `children; ::];

     .qp.theme[.gg.theme.blank]
         .qp.stack (
             .qp.segment[layout;`px__;`py__;`ppx__;`ppy__;::];
             .qp.point[layout;`px__;`py__;::])

Image

.qp.tree.layout

Layout for a hierarchical tree. An implementation of Reingold and Tilford's layout.

The layout results in a node table and an edge table. These tables can be used in a point and segment geometry to draw the tree (see the examples below).

Options:

  • [`inverty] whether the y axis should be inverted (useful for plotting horizontally or radially).

Parameters:

Name Type Description
t table table of a tree - should contain a scalar id column and a nested child column pointing to other ids
id symbol id column
children symbol children column
o dict | null options

Returns:

Name Type Description
<returns> dict Node and edges layout table
<returns>.nodes table
<returns>.edges table

Example: Basic tree example


     // Data has a nested child column
     t: .gg.cheat.i.assemble[];

     l: .qp.tree.layout[t;`id;`children;::];

     .qp.theme[.gg.theme.blank]
     .qp.stack (
         .qp.segment[l`edges;`x__;`y__;`x2__;`y2__;::]; 
         .qp.point[l`nodes;`x__;`y__;::])

Image

Example: Radial tree (polar coordinates)

     l: .qp.tree.layout[t;`id;`children;``inverty!(::;1b)];

     .qp.theme[.gg.theme.blank]
     .qp.stack (
         .qp.segment[l`edges;`y__;`x__;`y2__;`x2__]
             .qp.s.coord .gg.coords.polar; 
         .qp.point[l`nodes;`y__;`x__;::])

Image

Example: horizontal tree

     l: .qp.tree.layout[t;`id;`children;``inverty!(::;1b)];

     .qp.theme[.gg.theme.blank]
     .qp.stack (
         .qp.segment[l`edges;`y__;`x__;`y2__;`x2__;::]; 
         .qp.point[l`nodes;`y__;`x__;::])

Image

.qp.treemap.layout

Square space-filling tree map layout algorithm. The result is a table of rectangle positions. This can be joined to a table to display more information, or just visualized using a .qp.rect geometry as in the example below.

For a multi-level treemap, pass in the bounding rect of the next-level. See an example below for a two-level treemap.

Options:

  • [`x__`y__`x2__`y2__] bounding rect for a multi-level treemap (output of a previous run)
  • [`pad] whether to add a padding the each rectangle, false be default

Parameters:

Name Type Description
t table
x symbol Category/label column
y symbol Numeric column
o dict | null options

Returns:

Type Description
table treemap rectangle positions keyed by their label

Example: Basic treemap


     t: ([]Sector: 10?`8;MarketValue: 10?100);

     positions: .qp.treemap.layout[t; `Sector; `MarketValue; ::];
      //=> Sector  | x__      y__      x2__     y2__      
      //=> --------| -----------------------------------
      //=> cjfagcid| 0        0        33.4608  53.14286
      //=> hjfkgael| 0        53.14286 33.4608  100     
      //=> ...

     .qp.theme[.gg.theme.blank]
     .qp.rect[positions;`x__;`y__;`x2__;`y2__]
         .qp.s.aes[`fill; `Sector] ,
         .qp.s.geom[``colour!(::;0xffffff)]

Image

Example: Two-level treemap


     // Initial space fill of top-level hierarchy
     initialLayout: 0!.qp.treemap.layout[t;`Sector;`MarketValue;``pad!(::;1b)];

     // Divide each of the above with the next level 
     //   -- Just using random data for example
     subsectors: {([]Subsector: 50?`8;MarketValue: 50?100)} each til count t`Sector;
     positions: raze {
         @[;`Sector;:;x] 0!.qp.treemap.layout[y; `Subsector; `MarketValue; z]
         }'[t`Sector; subsectors; initialLayout];

     // Add back in the market value of each subsector
     positions: raze[subsectors] lj `Subsector xkey positions;

     .qp.theme[.gg.theme.blank]
     .qp.rect[positions;`x__;`y__;`x2__;`y2__]
         .qp.s.geom[``colour`alpha!(::;0xffffff;0xae)] ,
         .qp.s.aes[`fill`alpha; `Sector`MarketValue]

Image

.qp.treestack.layout

Layout for a hierarchical tree. A stack tree layout. Output is x, y, x2, y2 coordinates for .qp.rect.

Useful for weighted trees (trace timelines, etc). When used in polar coordinates, becomes a Sunburst Chart.

Options:

  • [`expand] expand children to take entire width of the parent.
  • [`filldepth] depth at which children are assigned a colour (default 4).
  • [`colours] a list of 0xrrggbb colours to use when filling.

Parameters:

Name Type Description
t table table of a tree - should contain a scalar id column and a nested child column pointing to other ids
id symbol id column
children symbol children column
weight symbol weight (numeric) column
o dict | null options

Returns:

Name Type Description
<returns> dict Node and edges layout table
<returns>.nodes table
<returns>.edges table

Example: Basic layout


      t: .gg.cheat.i.assemble[];
      t: update w:count each children from t;

      rr: .qp.treestack.layout[t;`id;`children;`w;``expand!(::;1b)];

     .qp.rect[rr;`x__;`y__;`x2__;`y2__] 
         .qp.s.geom[``colour!(::;0xffffff)]

Image

Example: Adding a fill and alpha scale


     .qp.theme[.gg.theme.blank , ``legend_use!(::;0b)]
     .qp.rect[rr;`x__;`y__;`x2__;`y2__] 
         .qp.s.geom[``colour!(::;0xffffff)] ,
         .qp.s.aes[`fill`alpha; `id`d__] ,
         .qp.s.scale[`fill; .gg.scale.colour.cat rr[`id]!rr`fill__]

Image

Example: Sunburst chart


     .qp.theme[.gg.theme.blank]
     .qp.theme[``legend_use!(::;0b)]
     .qp.rect[rr;`y__;`x__;`y2__;`x2__] 
         .qp.s.geom[``colour!(::;0xffffff)] ,
         .qp.s.aes[`fill`alpha; `id`d__] ,
         .qp.s.scale[`fill; .gg.scale.colour.cat rr[`id]!rr`fill__] ,
         .qp.s.coord[.gg.coords.polar]

Image