Creating New Packages
Adding Graph Bricks
We highly recommend reading the previous section, Adding Function Bricks, which covers the general aspects of creating a Brick. In this section, we will focus on the special case of graph Bricks.
Graph Bricks are visual nodes that enable the display of Vega-Lite graphs, leveraging the capabilities of Vega-Lite to allow users to create a diverse range of graphs for various purposes and objectives. We assume you are familiar with the standards and properties of Vega-Lite.

Creating Your First Graph Brick
Creating a graph Brick is identical to creating a function Brick, as described in the previous section, except for two key differences:
The use of
coded_flows_metadata
is mandatory, specifically through theframe_type
andvl_schema
parameters.key Description frame_type
Specifies the dimensions for a
graph
type Brick. It can be one of the predifined values (landscape
,portrait
orsquare
) or a custome value in the format of WidthxHeight in pixels, such as400x500
(minimum vaue at 400 pixels).vl_schema
Specifies the Vega-Lite schema for a
graph
type Brick.The Python function in the Brick file is a placeholder, used solely to define the structure and appearance of the Brick without performing any processing.
The following is an example of a graph Brick that represents a histogram:
from typing import Union
from coded_flows.types import List, DataSeries, NDArray, DataRecords, DataFrame
coded_flows_metadata = {
"display_name": "Histogram Display",
"description": "One dimensional histogram",
"type": "graph",
"icon": "chart-histogram",
"frame_type": "portrait",
"vl_schema": {
"mark": "bar",
"encoding": {
"x": {
"bin": {"maxbins": 40},
"field": "x",
"type": "quantitative",
"title": "",
},
"y": {"aggregate": "count", "title": ""},
},
},
}
def histogram(
x: Union[List, DataSeries, NDArray, DataRecords, DataFrame],
) -> Union[List, DataSeries, NDArray, DataRecords, DataFrame]:
return x
The core graph definition is contained in the vl_schema
, which follows a standard Vega-Lite schema. You do not need to specify data
, as CODED FLOWS will automatically apply it during display.
{
"mark": "bar",
"encoding": {
"x": {
"bin": { "maxbins": 40 },
"field": "x",
"type": "quantitative",
"title": ""
},
"y": { "aggregate": "count", "title": "" }
}
}
For the graph framing, we have chosen a portrait display, specified as "frame_type": "portrait"
.
The Brick's placeholder function must reference the Vega-Lite encoding rather than the field name to be passed as an input, in our case we will pass the x
encoding. Plus each encoding in the inputs must be returned as an output too.
# Example with one encoding
def histogram(x):
return x
# Example of multiple encodings
def histogram_heatmap_2d(x, y):
return x, y
Supported Encodings
- Position:
x
,y
,x2
,y2
,xError
,yError
,xError2
,yError2
- Polar Position:
theta
,radius
,theta2
,radius2
- Geographic Position:
longitude
,latitude
,longitude2
,latitude2
- Mark Properties:
color
,opacity
,fillOpacity
,strokeOpacity
,strokeWidth
,strokeDash
,size
,angle
,shape
- Text & Tooltip:
text
,tooltip
- Hyperlink:
href
- Description:
description
- Level of Detail:
detail
- Key:
key
- Order:
order
- Facet:
facet
,row
,column
Graph Bricks also require type hinting, which is always a Union
of List
, DataSeries
, NDArray
, DataRecords
, or DataFrame
.
# single encoding
def histogram(
x: Union[List, DataSeries, NDArray, DataRecords, DataFrame],
) -> Union[List, DataSeries, NDArray, DataRecords, DataFrame]:
return x
# multiple encodings
def histogram_heatmap_2d(
x: Union[List, DataSeries, NDArray, DataRecords, DataFrame],
y: Union[List, DataSeries, NDArray, DataRecords, DataFrame],
) -> Tuple[
Union[List, DataSeries, NDArray, DataRecords, DataFrame],
Union[List, DataSeries, NDArray, DataRecords, DataFrame],
]:
return x, y
Interactivity of a Graph Brick
In our example, we used the Vega-Lite schema below, which is somewhat rigid: it expects a field named x
in the input data, uses a fixed number of bins (maxbins: 40
), and only supports quantitative values.
{
"mark": "bar",
"encoding": {
"x": {
"bin": { "maxbins": 40 },
"field": "x",
"type": "quantitative",
"title": ""
},
"y": { "aggregate": "count", "title": "" }
}
}
This setup is a good candidate for adding interactivity through options
, allowing the user to dynamically change the field name or the number of bins. If the input data contains a field named distances
instead of x
, we can update the value accordingly to reflect that, making it more adaptable to different datasets.
The options
parameter follows the same structure as previously seen in the Bricks function, but with a specific naming convention for each option.
For example, to make maximum bins dynamic, we need to reference the maxbins
parameter, which is nested within multiple levels of the configuration hierarchy. Since maxbins
is located under the bin
dictionary key, which is under the x
encoding key, which is in turn under the encoding
key, we must use a path-like naming structure.
To reference this parameter, the option name must be set to encoding__x__bin__maxbins
, where each key in the hierarchy is separated by double underscores (__
).
from typing import Union
from coded_flows.types import List, DataSeries, NDArray, DataRecords, DataFrame
coded_flows_metadata = {
"display_name": "Histogram Display",
"description": "One dimensional histogram",
"type": "graph",
"icon": "chart-histogram",
"options": [
{
"name": "encoding__x__field",
"display_name": "values field for 'x'",
"type": "input",
"default": "x",
},
{
"name": "encoding__x__type",
"display_name": "'x' field type",
"type": "select",
"choices": [
"quantitative",
"ordinal",
"nominal",
],
"default": "quantitative",
},
{
"name": "encoding__x__bin__maxbins",
"display_name": "max bins for 'x'",
"type": "integer",
"step": 5,
"max": 300,
"min": 5,
"default": 40,
},
],
"frame_type": "portrait",
"vl_schema": {
"mark": "bar",
"encoding": {
"x": {
"bin": {"maxbins": 40},
"field": "x",
"type": "quantitative",
"title": "",
},
"y": {"aggregate": "count", "title": ""},
},
},
}
def histogram(
x: Union[List, DataSeries, NDArray, DataRecords, DataFrame],
options,
) -> Union[List, DataSeries, NDArray, DataRecords, DataFrame]:
return x
When working with array elements within the configuration, the naming convention extends to include array indices. For instance, in the stacked density example bellow, the counts
parameter is nested within the first transform operation (index 0) of the transform array. To make this parameter interactive, we use transform__0__counts
, where transform
is the top-level key, 0
represents the array index, and counts
is the specific parameter we want to control. This pattern applies universally: for any parameter nested within arrays, simply insert the coresponding index between the parent key and the target parameter, all separated by double underscores.
from typing import Union
from coded_flows.types import List, DataSeries, NDArray, DataRecords, DataFrame, Tuple
coded_flows_metadata = {
"display_name": "Stacked Density",
"description": "Stacked density plot combines smooth curves for multiple groups, revealing overlaps and distribution trends.",
"type": "graph",
"icon": "chart-sankey",
"frame_type": "landscape",
"options": [
{
"name": "encoding__x__field",
"display_name": "'x' data field",
"type": "input",
"default": "x",
},
{
"name": "encoding__color__field",
"display_name": "Aggregation field",
"type": "input",
"default": "color",
},
{
"name": "transform__0__counts",
"display_name": "Smoothed counts",
"type": "toggle",
"default": False,
},
],
"vl_schema": {
"mark": "area",
"transform": [
{
"density": "x",
"groupby": ["color"],
"counts": False,
"as": ["x", "density"],
}
],
"encoding": {
"x": {"field": "value", "type": "quantitative", "title": ""},
"y": {
"field": "density",
"type": "quantitative",
"stack": "zero",
"title": "",
},
"color": {"field": "color", "type": "nominal"},
},
},
}
def stacked_density(
x: Union[List, DataSeries, NDArray, DataRecords, DataFrame],
color: Union[List, DataSeries, NDArray, DataRecords, DataFrame],
options,
) -> Tuple[
Union[List, DataSeries, NDArray, DataRecords, DataFrame],
Union[List, DataSeries, NDArray, DataRecords, DataFrame],
]:
return x, color
After including this options
parameter (and don't forget to add it as an input to the main function), our Brick will now be enhanced with the following interactive menu:
