Pie1D
Pie1D widget shows how a whole is split into parts: every record is a segment of a ring, its size is the value of the record.
The total of all values can be shown in the center. Usually the data is aggregated, for example the sales of every client.
The data can be sourced either from a database or from external sources.
Basics
How does it look?

The widget shows:
- a segment for every record. The size of the segment is the value of the record, the label inside shows the value.
- the legend with the titles of the records. A click on a title in the legend hides the segment or shows it again, the total in the center is recalculated.
- the total in the center, see Total.
- the tooltip with the title and the value when the mouse is over a segment, see Tooltip.
The gear menu in the top right corner switches the widget between the chart and the table, see Table mode.
Rules for the data:
- one record is one segment. Aggregate the data: for example, one record per client with the sum of his sales.
- the segments go clockwise from the top in the order of the records returned by the backend.
- every record has a unique
id. It is required for the proper functioning of the widget and for the drilldown.
Options:
| Parameter | Description |
|---|---|
valueFieldKey |
Required. The field with the value of the segment. The field must be a number. |
titleFieldKey |
The field with the title of the segment: the legend, the tooltip and the colors of the segments. Without it the segments are colored by the value and the legend is not shown. |
descriptionFieldKey |
The list of fields for the tooltip, see Tooltip. |
valuePosition |
Where the values are shown: inner (default) or outer, see Label position. |
total |
The text in the center, see Total. |
How to add?
Example
Step1 Create DataResponseDTO with the fields of the segment: the title and the value.
@Getter
@Setter
@NoArgsConstructor
@Accessors(chain = true)
public class MyExampleDTO extends DataResponseDTO {
private String title;
private Long value;
}
Step2 Create DAO extends AbstractAnySourceBaseDAO<> implements AnySourceBaseDAO. It returns a record for every segment, each with a unique id.
@NonNull
private List<MyExampleDTO> getStats() {
return repository.getCustomPrj().stream()
.map(entity -> {
MyExampleDTO dto = new MyExampleDTO()
.setTitle(entity.clientName())
.setValue(entity.sum());
dto.setId(entity.clientId().toString());
return dto;
})
.toList();
}
Step3 Create Meta extends AnySourceFieldMetaBuilder.
@SuppressWarnings("EmptyMethod")
@Service
public class MyExampleMeta extends AnySourceFieldMetaBuilder<MyExampleDTO> {
@Override
public void buildRowDependentMeta(RowDependentFieldsMeta<MyExampleDTO> fields, BcDescription bc,
String id, String parentId) {
}
@Override
public void buildIndependentMeta(FieldsMeta<MyExampleDTO> fields, BcDescription bc, String parentId) {
}
}
Step4 Create Service extends AnySourceVersionAwareResponseService.
@SuppressWarnings({"java:S", "java:S"})
@RequiredArgsConstructor
@Service
public class MyExampleService extends AnySourceVersionAwareResponseService<MyExampleDTO, MyExampleDTO> {
@Getter(onMethod_ = @Override)
private final Class<MyExampleMeta> meta = MyExampleMeta.class;
@Getter(onMethod_ = @Override)
private final Class<MyExampleDao> dao = MyExampleDao.class;
@Override
protected CreateResult<MyExampleDTO> doCreateEntity(MyExampleDTO entity, BusinessComponent bc) {
throw new IllegalStateException();
}
@Override
protected ActionResultDTO<MyExampleDTO> doUpdateEntity(MyExampleDTO entity, MyExampleDTO data,
BusinessComponent bc) {
throw new IllegalStateException();
}
}
Step5 Create .widget.json with type Pie1D. Add the fields of the chart to fields and map them in options.chart1D.
options.chart1D sets which fields of the widget the chart uses:
| Parameter | Description |
|---|---|
valueFieldKey |
Required. The field with the value of the segment. The field must be a number. |
titleFieldKey |
The field with the title of the segment: the legend, the tooltip and the colors of the segments. Without it the segments are colored by the value and the legend is not shown. |
descriptionFieldKey |
The list of fields for the tooltip, see Tooltip. |
valuePosition |
Where the values are shown: inner (default) or outer, see Label position. |
total |
The text in the center, see Total. |
{
"name": "MyExamplePie",
"title": "Sales per client",
"type": "PieD",
"bc": "myExampleBc",
"fields": [
{
"title": "Sales",
"key": "value",
"type": "number"
},
{
"title": "Client",
"key": "title",
"type": "input"
}
],
"options": {
"chartD": {
"valueFieldKey": "value",
"titleFieldKey": "title",
"total": {
"func": "sum",
"description": "Total"
}
}
}
}
Step6 Add the widget to the corresponding .view.json.
{
"name": "myexamplepie",
"title": "PieD basic",
"template": "DashboardView",
"url": "/screen/myexample/view/myexamplepie",
"widgets": [
{
"widgetName": "MyExamplePie",
"position": 10,
"gridWidth": 24
}
],
"rolesAllowed": [
"CXBOX_USER"
]
}
Step7 Set PAGE_LIMIT of the business component in BC_PROPERTIES greater than the number of segments: the chart shows one page, see Page limit.
Title
Title Basic
Title for widget (optional)
There are types of:
constant title: shows constant text.constant title empty: if you want to visually connect widgets by them to be placed one under another
How does it look?


How to add?
Example
Step1 Add name for title to .widget.json.
{
"name": "MyExamplePie",
"title": "Sales per client",
"type": "PieD",
"bc": "myExampleBc",
"fields": [
{
"title": "Sales",
"key": "value",
"type": "number"
},
{
"title": "Client",
"key": "title",
"type": "input"
}
],
"options": {
"chartD": {
"valueFieldKey": "value",
"titleFieldKey": "title",
"total": {
"func": "sum",
"description": "Total"
}
}
}
}
Step1 Delete parameter title from .widget.json.
{
"name": "MyExamplePie",
"type": "PieD",
"bc": "myExampleBc",
"fields": [
{
"title": "Sales",
"key": "value",
"type": "number"
},
{
"title": "Client",
"key": "title",
"type": "input"
}
],
"options": {
"chartD": {
"valueFieldKey": "value",
"titleFieldKey": "title",
"total": {
"func": "sum",
"description": "Total"
}
}
}
}
Title Color
not applicable
Business component
This specifies the business component (BC) to which this widget belongs. A business component represents a specific part of a system that handles a particular business logic or data.
see more Business component
The data of a chart is usually calculated, so the samples use an AnySource business component: the DAO builds a record for every segment.
Give every record a unique id, see Basics.
Show condition
no show condition - recommended: widget always visible
-
show condition by current entity: not recommended for the chart. -
show condition by parent entity: condition can include boolean expression depending on parent entity. Parent field updates will trigger condition recalculation only on save or if field is force active shown on same view
Tips
It is recommended not to use Show condition when possible, because wide usage of this feature makes application hard to support.
How does it look?

Not recommended for the chart.

How to add?
Example
see Basics
Not recommended for the chart.
Step1 Add showCondition to .widget.json. see more showCondition
{
"name": "MyExamplePie",
"title": "Show condition widget",
"type": "PieD",
"bc": "myExampleBc",
"showCondition": {
"bcName": "myExampleBcParent",
"params": {
"fieldKey": "customFieldShowCondition",
"value": true
}
},
"fields": [
{
"title": "Sales",
"key": "value",
"type": "number"
},
{
"title": "Client",
"key": "title",
"type": "input"
}
],
"options": {
"chartD": {
"valueFieldKey": "value",
"titleFieldKey": "title",
"total": {
"func": "sum",
"description": "Total"
}
}
}
}
Fields
Fields Configuration. The fields array defines the fields of a segment.The other fields are shown in the table mode.
- "title"
Description: Field Title. It is the title of the column in the table mode.
Type: String(optional).
- "key"
Description: Name field to corresponding DataResponseDTO.
Type: String(required).
- "type"
Description: Field types. The field of valueFieldKey must be numeric.
Type: String(required).
A field with type hidden is not shown in the table mode. Use it for the values that only the drilldown filter needs.
How to add?
Example
Add field to .widget.json.
{
"name": "MyExamplePie",
"title": "Sales per client",
"type": "PieD",
"bc": "myExampleBc",
"fields": [
{
"title": "Sales",
"key": "value",
"type": "number"
},
{
"title": "Client",
"key": "title",
"type": "input"
}
],
"options": {
"chartD": {
"valueFieldKey": "value",
"titleFieldKey": "title",
"total": {
"func": "sum",
"description": "Total"
}
}
}
}
Options layout
options.layout - no use in this type.
Actions
not applicable
Additional properties
Tooltip
When the mouse is over a segment, the tooltip shows the title and the value of the segment. You can configure the tooltip not to be displayed.
How does it look?

How to add?
Example
Step1 Add the field with the text to the DataResponseDTO and fill it in the DAO.
@NonNull
private List<MyExampleDTO> getStats() {
return repository.getCustomPrj().stream()
.map(entity -> {
MyExampleDTO dto = new MyExampleDTO()
.setTitle(entity.clientName())
.setValue(entity.sum())
.setDescription(entity.clientName() + ": " + entity.salesCount() + " sales");
dto.setId(entity.clientId().toString());
return dto;
})
.toList();
}
When the mouse is over a segment, the tooltip shows the title and the value of the segment. options.chart1D.descriptionFieldKey replaces them with the text of the listed fields, separated by commas. Without titleFieldKey and descriptionFieldKey the tooltip is not shown.
{
"name": "MyExamplePie",
"title": "Sales per client",
"type": "PieD",
"bc": "myExampleBc",
"fields": [
{
"title": "Sales",
"key": "value",
"type": "number"
},
{
"title": "Client",
"key": "title",
"type": "input"
},
{
"title": "Description",
"key": "description",
"type": "input"
}
],
"options": {
"chartD": {
"valueFieldKey": "value",
"titleFieldKey": "title",
"descriptionFieldKey": [
"description"
],
"total": {
"func": "sum",
"description": "Total"
}
}
}
}
Color
Color sets the colors of the segments. By default every title gets its own color from the palette of the chart.
Calculated color
Calculated color can be used to change the color of a segment dynamically. It changes depending on business logic or data in the application. In the sample the key clients are blue, the others are grey.
Constant color
not recommended: Gives all segments one color, the segments cannot be told apart.
How does it look?

How to add?
Example
Step 1 Add custom field for color to corresponding DataResponseDTO. The field can contain a HEX color or be null.
@NonNull
private List<MyExampleDTO> getStats() {
return repository.getCustomPrj().stream()
.map(entity -> {
MyExampleDTO dto = new MyExampleDTO()
.setTitle(entity.clientName())
.setValue(entity.sum())
.setColor(entity.sum() > 7000 ? "#3AE" : "#BFBFBF");
dto.setId(entity.clientId().toString());
return dto;
})
.toList();
}
Step 2 Add "bgColorKey" : custom field for color to the field of valueFieldKey in .widget.json.
{
"name": "MyExamplePie",
"title": "Sales per client",
"type": "PieD",
"bc": "myExampleBc",
"fields": [
{
"title": "Sales",
"key": "value",
"type": "number",
"bgColorKey": "color"
},
{
"title": "Client",
"key": "title",
"type": "input"
},
{
"title": "Color",
"key": "color",
"type": "input"
}
],
"options": {
"chartD": {
"valueFieldKey": "value",
"titleFieldKey": "title",
"total": {
"func": "sum",
"description": "Total"
}
}
}
}
not recommended
Drilldown
DrillDown allows you to navigate to another view by a click on a segment. Target view and other drill-down parts can be calculated based on business logic of application.
In the sample a click on a segment opens the list of sales filtered by the client of the segment.
Also, it optionally allows you to filter data on target view before it will be opened see more DrillDown
How does it look?

How to add?
Example
Step1 Add "drillDown": true to the field of valueFieldKey in .widget.json.
{
"name": "MyExamplePie",
"title": "Sales per client",
"type": "PieD",
"bc": "myExampleBc",
"fields": [
{
"title": "Sales",
"key": "value",
"type": "number",
"drillDown": true
},
{
"title": "Client",
"key": "title",
"type": "input"
}
],
"options": {
"chartD": {
"valueFieldKey": "value",
"titleFieldKey": "title",
"total": {
"func": "sum",
"description": "Total"
}
}
}
}
Step2 Add fields.setDrilldown or fields.setDrilldownWithFilter for the field of valueFieldKey to corresponding FieldMetaBuilder.
@Override
public void buildRowDependentMeta(RowDependentFieldsMeta<MyExampleDTO> fields, BcDescription bc,
String id, String parentId) {
fields.setDrilldownWithFilter(
MyExampleDTO_.value,
DrillDownType.INNER,
"/screen/myexample/view/myexamplesales",
fc -> fc.add(
PlatformMyExampleController.myExampleBcSale,
MyExampleSaleDTO.class,
fb -> fb.input(MyExampleSaleDTO_.customField, fields.getCurrentValue(MyExampleDTO_.title)
.orElse(null))
)
);
}
Table mode
The gear menu in the top right corner has two modes:
Chart(default): the pie.Table: the same records as a table, a column for every field of the widget.
The mode is not saved: the widget opens in the chart mode.
How does it look?


How to add?
The mode switch is available for every chart, no settings are needed.
Icon
not available.
Total
Total is the text in the center of the pie.
| Parameter | Description |
|---|---|
func |
The aggregate function over the values of the shown segments: sum, avg, min, max. avg is rounded to two decimal places. |
argFieldKeys |
The fields for func instead of valueFieldKey, for example the count of sales when the segments show the sums. |
description |
The text above the result of func. |
value |
A constant text instead of func and description. Set either value or func, not both. |
A click on a title in the legend hides the segment, func is recalculated over the shown segments.
How does it look?



How to add?
Example
Add total with func and description to options.chart1D in .widget.json.
options.chart1D.total
{
"name": "MyExampleSum",
"title": "Sales per client",
"type": "PieD",
"bc": "myExampleBc",
"fields": [
{
"title": "Sales",
"key": "value",
"type": "number"
},
{
"title": "Client",
"key": "title",
"type": "input"
},
{
"title": "Sales count",
"key": "salesCount",
"type": "number"
}
],
"options": {
"chartD": {
"valueFieldKey": "value",
"titleFieldKey": "title",
"total": {
"func": "sum",
"description": "Total"
}
}
}
}
Step1 Add the field to the DataResponseDTO and fill it in the DAO.
@NonNull
private List<MyExampleDTO> getStats() {
return repository.getCustomPrj().stream()
.map(entity -> {
MyExampleDTO dto = new MyExampleDTO()
.setTitle(entity.clientName())
.setValue(entity.sum())
.setSalesCount(entity.salesCount());
dto.setId(entity.clientId().toString());
return dto;
})
.toList();
}
{
"name": "MyExampleArgFields",
"title": "Sales per client",
"type": "PieD",
"bc": "myExampleBc",
"fields": [
{
"title": "Sales",
"key": "value",
"type": "number"
},
{
"title": "Client",
"key": "title",
"type": "input"
},
{
"title": "Sales count",
"key": "salesCount",
"type": "number"
}
],
"options": {
"chartD": {
"valueFieldKey": "value",
"titleFieldKey": "title",
"total": {
"func": "sum",
"argFieldKeys": [
"salesCount"
],
"description": "Sales count"
}
}
}
}
Add total.value to options.chart1D in .widget.json.
{
"name": "MyExampleValue",
"title": "Sales per client",
"type": "PieD",
"bc": "myExampleBc",
"fields": [
{
"title": "Sales",
"key": "value",
"type": "number"
},
{
"title": "Client",
"key": "title",
"type": "input"
},
{
"title": "Sales count",
"key": "salesCount",
"type": "number"
}
],
"options": {
"chartD": {
"valueFieldKey": "value",
"titleFieldKey": "title",
"total": {
"value": "Q"
}
}
}
}
Hole in the center
You can set the size of the hole in the center of the pie, from 0 to 1, default 0.5.
0 draws a full pie without a hole, the total is shown over the segments.
How does it look?


How to add?
Example
Add total.innerSpace to options.chart1D in .widget.json.
options.chart1D.total.innerSpace
{
"name": "MyExampleInnerSpace",
"title": "Sales per client",
"type": "PieD",
"bc": "myExampleBc",
"fields": [
{
"title": "Sales",
"key": "value",
"type": "number"
},
{
"title": "Client",
"key": "title",
"type": "input"
},
{
"title": "Sales count",
"key": "salesCount",
"type": "number"
}
],
"options": {
"chartD": {
"valueFieldKey": "value",
"titleFieldKey": "title",
"total": {
"innerSpace": 0
}
}
}
}
Label position
You can set where the values of the segments are shown:
inner(default): inside the segments.outer: outside the pie, next to the segments.
How does it look?


How to add?
Example
Add valuePosition to options.chart1D in .widget.json.
options.chart1D.valuePosition
{
"name": "MyExampleOuter",
"title": "Sales per client",
"type": "PieD",
"bc": "myExampleBc",
"fields": [
{
"title": "Sales",
"key": "value",
"type": "number"
},
{
"title": "Client",
"key": "title",
"type": "input"
}
],
"options": {
"chartD": {
"valueFieldKey": "value",
"titleFieldKey": "title",
"valuePosition": "outer",
"total": {
"func": "sum",
"description": "Total"
}
}
}
}
Customization of displayed columns
not available.
Filtration
Basic
Works only in the table mode. In the chart mode there are no filters. After the switch back to the chart, the chart draws only the filtered records. The chart mode does not show that a filter is applied: the filter is cleared in the table mode. see more Filtration
FullTextSearch
Works only in the table mode with options.fullTextSearch in .widget.json: the search input is shown above the table. The widget sends the search text to the backend, and the AnySource DAO of the chart applies it itself. After the switch back to the chart, the chart draws only the filtered records. The chart mode does not show that a filter is applied: the filter is cleared in the table mode.
see FullTextSearch
Personal filter group
not available: the settings menu of the chart has only the Mode items, so there is no Save filters item.
Filter group
Works only in the table mode: the filter groups of the business component are shown above the table, as in a List widget. The widget sends the filter of the chosen group to the backend, and the AnySource DAO of the chart applies it itself. After the switch back to the chart, the chart draws only the filtered records. The chart mode does not show that a filter is applied: the filter is cleared in the table mode. see Filter group
Pagination
not applicable: the chart shows one page, see Page limit.
Export to Excel
not available.
Multi-upload files
not applicable
Sorting
Works only in the table mode for the fields with enableSort in the Meta. The widget sends the sort to the backend, and the AnySource DAO of the chart applies it itself. After the switch back to the chart, the chart draws the records in the sorted order.
see more Sorting
Page limit
The chart draws only the first page of the business component. When the business component has more records than the page limit,
the chart is not drawn: the widget opens in the table mode, the Chart mode is disabled and a warning icon explains why.
Set the page limit of the business component to the number of segments, see Page limit.
How does it look?

How to add?
Example
Step1 Set the page limit in the BC_PROPERTIES table. In the sample it is 5 for 9 segments.
Step2 The DAO returns the page asked by the widget. Pageable pageable = PageRequest.of(queryParameters.getPageNumber(), queryParameters.getPageSize());
List<MyExampleDTO> stats = getStats();
int from = (int) Math.min(pageable.getOffset(), stats.size());
int to = Math.min(from + pageable.getPageSize(), stats.size());
return new PageImpl<>(stats.subList(from, to), pageable, stats.size());
No data
When the backend returns no records, the widget shows the "No data" placeholder instead of the chart.
Parent-child
not available in the chart mode: a click on a segment does not select the record, the child widgets do not change. In the table mode a click on a row selects the record, and the child widgets show the data of this record.