Calculated properties specification
TypeScript type: CalculatedPropertiesSpecification.
This content modifier allows including additional calculated properties into the content.
Attributes
Name | Required? | Type | Default |
---|---|---|---|
label |
Yes | string |
|
value |
No | ECExpression | |
type |
No | "string" | "int" | "long" | "dateTime" | "boolean" | "bool" | "double" |
"string" |
categoryId |
No | string | CategoryIdentifier |
No override |
renderer |
No | RendererSpecification |
No override |
editor |
No | PropertyEditorSpecification |
No override |
priority |
No | number |
1000 |
extendedData |
No | { [key: string]: ECExpression } |
Attribute: label
Specifies label of the calculated property. Supports localization.
Type | string |
Is Required | Yes |
// There's a content rule for returning content of given `bis.Subject` instance. The produced content is customized to
// additionally have a calculated "My Calculated Property" property.
const ruleset: Ruleset = {
id: "example",
rules: [
{
ruleType: "Content",
specifications: [
{
specType: "SelectedNodeInstances",
calculatedProperties: [
{
label: "My Calculated Property",
value: `123`,
},
],
},
],
},
],
};
Attribute: value
Defines an expression to calculate the value. The expression can use ECInstance and Ruleset Variables symbol contexts.
Type | ECExpression |
Is Required | No |
Default Value | undefined |
// There's a content rule for returning content of given `bis.GeometricElement3d` instance. The produced content is
// customized to additionally have a calculated "Element Volume" property whose value is calculated based on
// element's `BBoxHigh` and `BBoxLow` property values.
const ruleset: Ruleset = {
id: "example",
rules: [
{
ruleType: "Content",
specifications: [
{
specType: "SelectedNodeInstances",
calculatedProperties: [
{
label: "Element Volume",
value: "(this.BBoxHigh.x - this.BBoxLow.x) * (this.BBoxHigh.y - this.BBoxLow.y) * (this.BBoxHigh.z - this.BBoxLow.z)",
},
],
},
],
},
],
};
Attribute: type
Specifies return type of the calculated property. Presentation library tries to map the type of the evaluated expression to the requested type.
If evaluated expression cannot be converted to the specified type, an error will be thrown when requesting content with the error
message: Calculated property evaluated to a type that couldn't be converted to requested type
. For example, if the specified type is dateTime
for the expression 2 * 2
,
an error would be thrown, since evaluated expression would have a type of int
.
Type | "string" | "int" | "long" | "dateTime" | "boolean" | "bool" | "double" |
Is Required | No |
Default Value | "string" |
// There's a content rule for returning content of given `bis.GeometricElement3d` instance. The produced content is customized to
// additionally have a calculated "My Calculated Property" property with a custom return "type"
const ruleset: Ruleset = {
id: "example",
rules: [
{
ruleType: "Content",
specifications: [
{
specType: "SelectedNodeInstances",
calculatedProperties: [
{
label: "My Calculated Property",
value: "2+2",
type: "int"
},
],
},
],
},
],
};
Attribute: categoryId
The attribute allows moving the property into a different category. There are several options:
Reference a category by ID used in
PropertyCategorySpecification
in the current context. The current context contains categories specified in the same content specification or content modifiers that are applied on the same or base ECClass as this property specification.Move to
DefaultParent
category. This is useful when using with related properties, to avoid putting them inside a special related class category and instead show them next to properties of the source class.Move to
Root
category. This is useful when using with related properties, to avoid putting them inside a special related class category and instead show them in the root category.
See property categorization page for more details.
Type | string | CategoryIdentifier |
Is Required | No |
Default Value | No override |
// There's a content rule for returning content of given `bis.Subject` instance. The produced content is customized to
// additionally have a calculated "My Calculated Property" property that is placed into a custom category by
// assigning it a `categoryId`.
const ruleset: Ruleset = {
id: "example",
rules: [
{
ruleType: "Content",
specifications: [
{
specType: "SelectedNodeInstances",
propertyCategories: [
{
id: "custom-category",
label: "Custom",
},
],
calculatedProperties: [
{
label: "My Calculated Property",
value: "123",
categoryId: "custom-category",
},
],
},
],
},
],
};
Attribute: renderer
Custom property renderer specification that allows assigning a custom value renderer to be used in UI. The specification is used to set up Field.renderer for this property and it's up to the UI component to make sure appropriate renderer is used to render the property.
See Custom property value renderers page for a list of available renderers or how to register a custom one.
Type | RendererSpecification |
Is Required | No |
Default Value | No override |
// There's a content rule for returning content of given `bis.Subject` instance. The produced content is customized to
// additionally have a calculated "My Calculated Property" property with a custom "my-renderer" renderer.
const ruleset: Ruleset = {
id: "example",
rules: [
{
ruleType: "Content",
specifications: [
{
specType: "SelectedNodeInstances",
calculatedProperties: [
{
label: "My Calculated property",
value: "123",
renderer: {
rendererName: "my-renderer",
},
},
],
},
],
},
],
};
// Ensure the calculated property field is assigned the "my-renderer" renderer
const content = await Presentation.presentation.getContentIterator({
imodel,
rulesetOrId: ruleset,
keys: new KeySet([{ className: "BisCore:Subject", id: "0x1" }]),
descriptor: {},
});
expect(content!.descriptor.fields).to.containSubset([
{
label: "My Calculated property",
renderer: {
name: "my-renderer",
},
},
]);
Attribute editor
Custom property editor specification that allows assigning a custom value editor to be used in UI.
Type | PropertyEditorSpecification |
Is Required | No |
Default Value | No override |
// There's a content rule for returning content of given `bis.Subject` instance. The produced content is customized to
// additionally have a calculated "My Calculated Property" property with a custom "my-editor" editor.
const ruleset: Ruleset = {
id: "example",
rules: [
{
ruleType: "Content",
specifications: [
{
specType: "SelectedNodeInstances",
calculatedProperties: [
{
label: "My Calculated property",
value: "123",
editor: {
editorName: "my-editor",
},
},
],
},
],
},
],
};
// Ensure the calculated property field is assigned the "my-editor" editor
const content = await Presentation.presentation.getContentIterator({
imodel,
rulesetOrId: ruleset,
keys: new KeySet([{ className: "BisCore:Subject", id: "0x1" }]),
descriptor: {},
});
expect(content!.descriptor.fields).to.containSubset([
{
label: "My Calculated property",
editor: {
name: "my-editor",
},
},
]);
Attribute: priority
Assign a custom Field.priority to the property. It's up to the UI component to make sure that priority is respected - properties with higher priority should appear before or above properties with lower priority.
Type | number |
Is Required | No |
Default Value | 1000 |
// There's a content rule for returning content of given `bis.Subject` instance. The produced content is customized to
// additionally have a "My Calculated Property" property with priority set to `9999`. This should make the property
// appear at the top in the UI, since generally properties have a priority of `1000`.
const ruleset: Ruleset = {
id: "example",
rules: [
{
ruleType: "Content",
specifications: [
{
specType: "SelectedNodeInstances",
calculatedProperties: [
{
label: "My Calculated Property",
value: `123`,
priority: 9999,
},
],
},
],
},
],
};
priority: 9999 |
priority: -9999 |
---|---|
Attribute: extendedData
A map of ECExpressions whose evaluation results are used as extended data values.
Type | { [key: string]: ECExpression } |
Is Required | No |
// There's a content rule for returning content of given `bis.Subject` instance. The produced content is customized to
// additionally have a calculated "My Calculated Property" property that has extended data assigned.
const ruleset: Ruleset = {
id: "example",
rules: [
{
ruleType: "Content",
specifications: [
{
specType: "SelectedNodeInstances",
calculatedProperties: [
{
label: "My Calculated Property",
value: "123",
extendedData: {
extendedDataInt: "2*2",
extendedDataStr: "\"xxx\""
},
},
],
},
],
},
],
};
// Ensure that the calculated property field has `extendedData` items assigned to it.
const content = await Presentation.presentation.getContentIterator({
imodel,
rulesetOrId: ruleset,
keys: new KeySet([{ className: "BisCore:Subject", id: "0x1" }]),
descriptor: {},
});
expect(content!.descriptor.fields).to.containSubset([
{
label: "My Calculated Property",
extendedData: {
extendedDataInt: 4,
extendedDataStr: "xxx"
},
},
]);
Last Updated: 17 September, 2024