This is an EXPERIMENTAL feature. Use with caution in production templates.

Overview

The Subsheet Widget provides a way to automatically create calculations that are dependent on the result of a master sheet. The typical scenario is a calculator like portalFrameAnalysis which performs analysis on certain member sizes, but the design must be linked to and performed in timberMember calculators for each element. Instead of manually creating the portalFrameAnalysis and each of the timberMember calculators and linking them, you only need to create the portalFrameAnalysis and everything is automatically synchronized!

API Structure

The subsheet widget can be dragged from the sidebar and has multiple conditions like the equation widget, but must have an array of objects for the result.
{
  "label": "YOUR LABEL VALUE",
  "symbol": "String (Latex)",
  "equation": [
    {
      "condition": "@default",
      "result": "[{
        id: 
        name:
        sheetTemplate:
        capability:
        preset:
        commonInputs:
        linkTo:
        linkFromIndex:                        
      },
      { ... }]"
    }
  ],
  "referenceId": "subsheet_widget",
  "visibleIf": "true / false"
}

Configuration Parameters

id
string
required
Unique identifier for each subsheet. Typically string(row[x]) when iterating over table, which pulls the value in the Xth column of the 1st argument.
name
string
required
Visible to user so should be meaningful. Best to have 1st argument have a column of labels like β€œLeft Leg”, β€œRight Leg”. Example: string(row[y]) when iterating over table.
sheetTemplate
string
required
Subsheet name (e.g., timberMember)
capability
string
required
Any string that will match the β€œcapability” key added to the subsheet (e.g., elementLinking)
preset
string
required
The preset to use for the subsheet (e.g., elementLink)
commonInputs
array
required
Array of reference IDs of widgets in the subsheet that are shared. Within parent sheet these are accessed per special syntax below.
Reference ID of subsheet table widget that receives all the results export (e.g., link_table)
The row of data selected in the subsheet (0-based). Typically a column in 1st argument table that has an incrementing integer (e.g., row[1] when iterating over table)

Important Constraints

Critical Requirements:
  1. The keys (e.g., id, name) must not have any data that is derived from one of the commonInput widgets. This will lead to cyclic calculation errors.
  2. The subsheets cannot have defaultValue formulas in any of the commonInputs. For example, if connecting to member, don’t set a defaultValue in the timberMember subsheet of =projectDefault(xx) in any preset or the defaultValue key.
  3. The subsheetData that is mapped over must not have any data that is derived from one of the commonInput widgets.

Iteration for Multiple Subsheets

When the number of subsheets varies dynamically (e.g., based on the number of elements in a frame analysis), you can iterate over a table using the mapRows function.

Dynamic Sheet Management

When the number of subsheets changes, sheets will be added or deleted accordingly. The subsheet input data will be preserved only if the newly created subsheet shares the same id as the previously deleted subsheet. Example: A beam analysis with 3 spans that changes to 2 spans will delete the 3rd subsheet. If the ids were [0,1,2] then [0,1], and later a third span is re-added with matching IDs ([0,1,2]), the previous subsheet will be recreated with all its old inputs.

MapRows Function

ParameterTypeDescription
subsheetDatastringTable to iterate over
fn(tableRow)functionFunction that returns subsheet configuration object for each row
mapRows(subsheetData, f(row) = { 
  id: string(row[2]), // Must be unique
  name: string(row[2]),
  sheetTemplate: 'timberMember',
  capability: 'elementLinking',
  preset: 'elementLink',
  commonInputs: ['member','n_{com}'],
  linkTo: 'link_table',
  linkFromIndex: row[1] // Must be integer
})

Implementation Steps

1. Create Template

Create a template based on Portal Frame or Truss template.

2. Add Export Table

Add a table for exported inputs (as you would for normal linking).

3. Add Subsheet Widget

Add a Subsheet Widget and configure it according to the API above.

4. Update Capabilities

Add/Update the capabilities array in the subsheet header:
"data": {
  "attributes": {
    "capabilities": ["elementLinking"]
  }
}

5. Reference Values

Reference the subsheet widget values throughout the master sheet using the special syntax below.

Referencing CommonInput Values

When working inside the super sheet, use this special syntax to reference any commonInputs:

Input Widgets

subsheetWidgetRefId.subsheetId.commonInput
// Example: subsheetWidget.LeftLeg.n_com

Lookup Widgets (Data Table or Shared Table)

subsheetWidgetRefId.subsheetId.commonInput.commonInputColumn
// Example: subsheetWidget.LeftLeg.member.Ixx

Special Characters

When you have special characters (-, /, space), use square brackets instead of dots:
// With dots: subsheetWidget.LeftLeg.n_com
// With brackets: subsheetWidget.LeftLeg["n-com"]

Example: Data Table Lookup

{
  "dataColumns": [
    {
      "label": "Orientation Axis",
      "referenceId": "axis" // This is the commonInputColumn
    },
    {
      "label": "Orientation Direction", 
      "referenceId": "direction"
    }
  ],
  "dataTable": [
    ["Loaded in 'L' Axis", "+y"],
    ["Loaded in '7' Axis", "-y"]
  ],
  "referenceId": "orient_load"
}

Usage Workflow

  1. Master Sheet Setup: Go to master sheet and set up your common inputs
  2. Subsheet Access: Go to the subsheet and results should be available
  3. Bi-directional Updates: Change common inputs in the subsheet and the master sheet will re-calculate automatically
As the UI develops, this usage section will be expanded with more detailed workflow examples.

Example: Portal Frame Analysis

Instead of manually generating the array of objects, map over each row in the elemExport table:
Portal frame analysis example showing element export table
mapRows(exportTable, f(row) = { // 1-indexed 
  id: string(row[2]), // e.g. "LeftLeg" - must be unique
  name: string(row[2]),
  sheetTemplate: 'timberMember',
  capability: 'elementLinking', 
  preset: 'elementLink',
  commonInputs: ['member','n_{com}'],
  linkTo: 'link_table',
  linkFromIndex: row[1] // must be integer
})

Best Practices

  1. Consistent IDs: Use consistent IDs for dynamically sized arrays of subsheets to preserve user input data
  2. Avoid Cycles: Ensure no cyclic dependencies between commonInputs and derived data
  3. Testing: Thoroughly test dynamic sheet creation and deletion scenarios
  4. Documentation: Document the relationship between master and subsheets clearly
This feature is experimental. Monitor for any unexpected behavior and report issues to the development team.