Configuring data
This package contains a sole component named DashJsonGrid. To use this component,
we can start from this minimal example:
- Codes
- Results
import dash
import dash_json_grid as djg
app = dash.Dash("demo")
app.layout = djg.DashJsonGrid(
data=1
)
if __name__ == "__main__":
app.run()
The dash app is expected to render the following result:
| 1 | 1 |
Sanitization
Simply change the data property of DashJsonGrid, users will be able to view the
results:
- Codes
- Results
...
app.layout = djg.DashJsonGrid(
data=[1]
)
...
The dash app is expected to render the following result:
| 1 | 1 |
We can find that the result does not change compared to the minimal example. That's
because all literal value that is passed to data but not a
Sequence or a
Mapping will be automatically converted to
a sequence with only one element. In other words, data=1 will be sanitized as
data=[1] implicitly.
Dash will not automatically serialize a customized class. Therefore, if the data you
provide contains instances of customized classes, a good way is to convert the
instances to str.
Render a sequence
The following example modifies the data property and renders a sequence.
- Codes
- Results
...
app.layout = djg.DashJsonGrid(
data=[1, 2.0, "3", None, True]
)
...
The dash app is expected to render the following result:
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | null |
| 5 | true |
A sequence containing literal or unstructured values will be rendered as a vertical list containing an index column and a value column.
Render a mapping
The following example modifies the data property and renders a mapping.
- Codes
- Results
...
app.layout = djg.DashJsonGrid(
data={"key1": 1, "key2": "str", "key3": True, "key4": None}
)
...
The dash app is expected to render the following result:
| key1 | 1 |
| key2 | str |
| key3 | true |
| key4 | null |
A mapping not belonging to a table will be rendered as a vertical list containing a key column and a value column.
Render a table
The following example modifies the data property and renders a table.
- Codes
- Results
...
app.layout = djg.DashJsonGrid(
data=[
{"key1": 1, "key2": "str"},
{"key1": True, "key2": None},
{"key1": 3.0},
{"key1": False, "key2": None, "key3": 4.0},
{"key5": "?"},
]
)
...
The dash app is expected to render the following result:
| key1 | key2 | key3 | key5 | |
|---|---|---|---|---|
| 1 | 1 | str | undefined | undefined |
| 2 | true | null | undefined | undefined |
| 3 | 3 | undefined | undefined | undefined |
| 4 | false | null | 4 | undefined |
| 5 | undefined | undefined | undefined | ? |
A table will be constructed when a Sequence is detected and all of its elements are
Mappings. In this case, the Sequence itself will not be rendered as an indexed list,
and the members of the sequence will not be rendered as key-value lists. Instead, the
whole list will be rendered as a table.
The indicies of the table are just corresponding to the elements in the sequence. The
columns of the table is a union of all appeared
keywords in all elements. For any row, if some keywords are missing, the value will
be marked by undefined.
Render the complicated, nested, and multi-level data
The following example shows the performance of rendering the complicated data. It has
multiple levels, and the table, sequence, and mapping can be nested in each other.
DashJsonGrid will automatically detect how to properly render the data, so the users
can get rid of formatting the complicated data into nested HTML components.
- Codes
- Results
...
app.layout = djg.DashJsonGrid(
data={
"literal": 1,
"sequence": [1, 2.0, "3", None, True],
"mapping": {"key1": 1, "key2": "str", "key3": True, "key4": None},
"table": [
{"key1": 1, "key2": "str"},
{"key1": True, "key2": None},
{"key1": 3.0},
{"key1": False, "key2": None, "key3": 4.0},
{"key5": "?"},
],
"not-a-table": [
{"val1": 1},
2.0,
["a", "b", "c"],
[{"key1": ["a"], "key2": 2, "key3": {"val1": True}}],
[{"key3": 1}],
],
}
)
...
The dash app is expected to render the following result:
| literal | 1 |
| sequence | [+]sequence [5] |
| mapping | [+]mapping {} |
| table | [+]table [5] |
| not-a-table | [+]not-a-table [5] |
Expand a part of the data
For a complicated data property like the above example, it may be necessary to expand
a small part of the data by default. The following example shows how to configure this
partial expanding feature by the property default_expand_key_tree:
- Codes
- Results
...
app.layout = djg.DashJsonGrid(
data=...,
default_expand_key_tree={"not-a-table": {"2": True}}
)
...
The dash app is expected to render the following result:
| literal | 1 | ||||||||||||||||
| sequence | [+]sequence [5] | ||||||||||||||||
| mapping | [+]mapping {} | ||||||||||||||||
| table | [+]table [5] | ||||||||||||||||
| not-a-table | [-]not-a-table [5]
|
Note that the leaf node of default_expand_key_tree should be boolean values. Any
leaf node set by True will let that route expanded.
Alternative initializations
The data can be fed into the component by another two initialization methods.
- By a string
- By a file
Users can also initialize the component by a JSON string:
app.layout = dash_json_grid.DashJsonGrid.from_str(
json_string: str, ...
)
By using this method, the first argument json_string will be a string that can be
decoded by a JSON decoder. In this case, data should not be used.
It is also allowed to use a JSON file to initialize the component directly:
app.layout = dash_json_grid.DashJsonGrid.from_file(
json_file: str | os.PathLike | IO[str], ...
)
By using this method, the first argument json_file will be path pointing to a JSON
file or a file-like object. In this case, data should not be used.
Note that json_string and json_file are translated to data during the
initialization. Therefore, json_string or json_file will not be properties that can
be accessed by a callback.