Show data & tables
The DataView
is a powerful feature, in which, for example, the results of one or more
calculations can be shown immediately (e.g. the volume of an object). The entries in a DataView
can be divided into
three levels.
Data view
Implementation
The following steps have to be performed to visualize the desired results:
- Create the data group(s) consisting of
DataItems
for visualization. - Pass the group(s) to a decorated view method that returns a
DataResult
.
from viktor.views import DataGroup, DataItem, DataResult, DataView
class Controller(ViktorController):
...
@DataView("OUTPUT", duration_guess=1)
def visualize_data(self, params, **kwargs):
data = DataGroup(
DataItem('Data item 1', 123)
)
return DataResult(data)
Multilayered DataGroup
Below an example is given of a multilayered output group (maximum of three layers deep):
@DataView("OUTPUT", duration_guess=1)
def visualize_data(self, params, **kwargs):
value_a = 1
value_b = 2 * value_a
value_total = value_a + value_b
data = DataGroup(
group_a=DataItem('Group A', 'some result', subgroup=DataGroup(
sub_group=DataItem('Result', 1, suffix='N')
)),
group_b=DataItem('Group B', '', subgroup=DataGroup(
sub_group=DataItem('Sub group', value_total, prefix='€', subgroup=DataGroup(
value_a=DataItem('Value A', value_a, prefix='€'),
value_b=DataItem('Value B', value_b, prefix='€', explanation_label='this value is a result of multiplying Value A by 2')
))
))
)
return DataResult(data)
The explanation_label
can be used to inform the user. The output result will look like this:
Example DataView
Positional or key-worded DataItem?
In previous examples, we saw a DataGroup created with and without the use of keyword arguments. Using keywords is
necessary to link the corresponding DataItem
to the Summary
. A detailed guide of the Summary
can be found
here.
Dynamic group length
The structure of DataGroup
s allows for dynamic creation/addition of data to the overall result, as long as the
maximum number of items is not exceeded. An example of dynamically creating data items is shown below:
shopping_cart = {
'Apple': 0.20,
'Pineapple': 1.80,
'Milk': 1
}
# loop through products
total_cost = 0
data_items = []
for item, price in shopping_cart.items():
data_items.append(DataItem(item, price, prefix='€'))
total_cost += price
# construct data group
data_group = DataGroup(
DataItem('Shopping cart', total_cost, prefix='€', subgroup=DataGroup(*data_items))
)
Setting warning/error statuses
Sometimes it is desired to warn a user when a result exceeds a certain values. For these cases, the status
and
status_message
arguments of a DataItem
can be considered. Suppose we want to warn the user if our shopping cart of
the example above exceeds 5 euros, we can add the following:
shopping_cart.update({
'Cheese': 2.50
})
# loop through products
...
# construct data group
if total_cost <= 5:
status = DataStatus.SUCCESS
status_msg = ''
else:
status = DataStatus.WARNING
status_msg = 'Mind your wallet!'
data_group = DataGroup(
DataItem('Shopping cart', total_cost, prefix='€', status=status, status_message=status_msg, subgroup=DataGroup(*data_items))
)
Example status message
Testing
mock_View
decorator for easier testing of view methods
Methods decorated with @DataView
need to be mocked within
the context of (automated) testing:
import unittest
from viktor.testing import mock_View
from app.my_entity_type.controller import MyEntityTypeController
class TestMyEntityTypeController(unittest.TestCase):
@mock_View(MyEntityTypeController)
def test_data_view(self):
params = ...
result = MyEntityTypeController().data_view(params=params)
self.assertEqual(result.data, ...)