How to add a decision table

A how-to guide for adding a decision table.

Introduction

Would you like to hide/show controls and set control properties based on previous inputs in the control panel? Then add a decision table to your solution by following these steps.

The decision table must contain a column for every input that influences or is dependent on another input. The rows represent the combinations of those inputs (e.g. the control visibility and properties). As the user sets values for those inputs, the table rows are filtered down to a sub-set of input visibility states and property options.

Prerequisites

  • You configured the frames and routes for your solution.

1. Add a new EntityDataStore

  • Add a new EntityDataStore, which will contain your decision table.
  • Define the properties as usual.
  • Properties that can be null (e.g. when hidden) should be set to nullable and given a default value of null.
  my-entity-data-store:
    kind: EntityDataStore
    properties:
      space:
        type: String
      finish:
        type: String
      product-code:
        type: String
      price:
        type: Number
      quantity-min:
        type: Number
      quantity-max:
        type: Number
      corrosion-protection:
        type: Boolean

2. Define your decision table

To define the decision table, define entities in your entity datastore. The entities can be added in two ways:

  • Either from static records:
    You can define the list of entities with key-value pairs in the solution.yaml file.

    • Each entity defines a final decision.
    • Each property can define a decision point or a dynamic value as a consequence of the previous decisions.

    đź’ˇThe keys in the entities should match the EntityDataStore properties.

    For example the EntityDataStore below has different paint types as entities with varying prices.

      my-entity-data-store:
        kind: EntityDataStore
        entities:
          - space: Indoor
            finish: Matte
            product-code: "I-M-0000"
            price: 5
            quantity-min: 5
            quantity-max: 15
            corrosion-protection: false
          - space: Indoor
            finish: Glossy
            product-code: "I-G-0000"
            price: 10
            quantity-min: 10
            quantity-max: 20
            corrosion-protection: true
          ...
        properties:
          ...
    
  • Or from a CSV file: You can define and manage entities in a CSV file for convenience instead.

    • To define your decision table, compile your CSV file.
      • Each column can define a decision point or a dynamic value as a consequence of the previous decisions.
      • Each row defines a final decision, and represents an entity in the EntityDataStore.

    đź’ˇThe columns in the CSV file should match the entity datastore properties.
    Note that empty cells will be interpreted as null in the entity and other values are casted to their corresponding type.

    For example the table below has different paint types in each row with varying prices.

    space finish product-code price quantity-min quantity-max corrosion-protection
    Indoor Matte I-M-0000 5 5 15
    Indoor Glossy I-G-0000 10 10 20
    Outdoor Glossy O-G-0000 10 10 20 true
    Outdoor Matte O-M-0000 10 10 25 true

    đź’ˇYou can export a CSV file from your preferred spreadsheet editor.

    • Save your .csv file to the solution folder.

    • Define entities with the fromCsvFile tag and refer to your CSV file.

      The configuration should look similar to the example below:

      my-entity-data-store:
        kind: EntityDataStore
        fromCsvFile: my-csv-file-1.csv
        properties:
          ...
      

    ❗To save a new version of the CSV file with updated content, you need to rename your file (e.g. “my-csv-file-2.csv”).

3. Add a control panel

  • Add a control panel with kind: ControlPanel to your solution.
  • Define the controlsas usual. The controls, which are linked to the decision table, need to have the same names as the properties defined in the entity datastore.

đź’ˇControls that are hidden based on the decision table should be set to required: false, so the control panel remains valid when submitted.

The configuration should look similar to the example below:

my-control-panel:
  kind: ControlPanel
  controls:
    space:
      kind: Dropdown
      label: Space
      choices: []
    finish:
      kind: Dropdown
      label: Finish
      choices: []
    product-code:
      kind: Dropdown
      label: Product code
      choices: []
    quantity:
      kind: NumberInput
      label: Quantity
    corrosion-protection:
      kind: Toggle
      label: Corrosion Protection?
      value: false

4. Subscribe the entity datastore to the control panel

Based on the decisions made in the user interface, the entities can be filtered. To filter the decision table with inputs, subscribe yourEntityDataStore to your ControlPanel . The aim here is to filter the entities down so that the controls can reflect this filtered set.

  • Under your EntityDataStore define a subscription with kind: ControlPanel .
  • Define the source and frame .
  • Define filterByControls which should contain the controls that represent the decisions of the decision table
my-entity-data-store:
  kind: EntityDataStore
  entities: [ ... ]
  properties: { ... }
  subscribe:
    - kind: ControlPanel
      frame: my-home-frame
      source: my-control-panel
      filterByControls:
        - space
        - finish
        - product-code

5. Subscribe the control panel to the entity datastore

To populate the control panel inputs with the decision table, subscribe your ControlPanel to your EntityDataStore.

  • Under your ControlPanel define a subscription with kind: EntityDataStore.
  • Define the source and frame .
  • Use the setControls tag to set properties of your controls based on the decision table.
    • Define the control’s name that you’d like to link to the decision table.
    • You can set different types of properties of the controls with the control setter. See the controlsetter configuration docs.
    • Optionally define which decisions have consequences on a control’s properties by filtering the entities.
my-control-panel:
  kind: ControlPanel
  controls:
    space:
      kind: Dropdown
      label: Space
      choices: []
    finish:
      kind: Dropdown
      label: Finish
      choices: []
    product-code:
      kind: Dropdown
      label: Product family
      choices: []
    quantity:
      kind: NumberInput
      label: Quantity
    corrosion-protection:
      kind: Toggle
      label: Corrosion Protection?
      value: false
  subscribe:
    - kind: EntityDataStore
      frame: my-home-frame
      source: my-entity-data-store
      setControls:
        space:
          type: setDropDownChoices
        finish:
          type: setDropDownChoices
          filterChoices: [space]
        product-code:
          type: setDropDownChoices
          filterChoices: [space,finish]
        quantity:
          type: setMinMax
          minProperty: quantity-min
          maxProperty: quantity-max
          filterBy: [space, finish, product-code]
        corrosion-protection:
          type: setVisibility
          filterBy: [space, finish, product-code]

6. [Optional] Subscribe the model to the entity datastore

To run your Grasshopper model with all the remaining entities in the filtered decision table:

  • Subscribe your Model to the EntityDataStore .
  • Define the source and frame .
  • Define the name of the input to receive the filtered entities with the setInput tag.
  • Define which inputs to use as filters with the filterEntities tag.
my-model:
  kind: Model
  modelFile: my-gh-model.gh
  subscribe:
    - kind: EntityDataStore # subscribe model to entity data store to get filter set
      frame: my-home-frame
      source: my-entity-data-store
      setInput: my-gh-input
      filterEntities: [space, finish, product-code]

See the image below as an example.

Configuration

See the EntityDataStore configuration docs and ControlPanel configuration docs for more information.