Get views grouped by sheet

I want to access data from view, and i want to access them by sheets. Currently, i can access sheets like so:

{
  stream(id: "my-stream-id") {
    id
    branch {
      commits {
        items {
          id
          branchName
          referencedObject
          totalChildrenCount
        }
      }
    }
  }
}

From the query above, i use the result from referenceObject to access sheets like so:

query($myQuery: [JSONObject!]) {
  stream(id: "my-stream-id") {
    id
    name
    object(id: "reference-object-string") {
      id
      children(query:$myQuery) {
        cursor
        totalCount
        objects {
          data
        }
      }
    } 
  }
}

Where my query is:

{
  "myQuery": [{
    "field": "category",
    "value": "Sheets",
    "operator": "="
  }]
}

From this query, i find all sheets, and i can access sheet name, date, revisions, and so on, but i cannot find anything regarding views in this query. “Where” do i find the views in a sheet?

Hey @ONO ,

I’m not sure if we are exporting the referenced views on sheets.

@ONO and @gokermu, I didn’t know, but I dug into this a little.

Views and Sheets are all stored in Speckle as Object.BuiltElement.View or Objects.BuiltElements.View:Objects.BuiltElements.View3D for 3D views.

We send both Views and sheets as individual objects and not nested one in the other because while views can only exist on one sheet, there can be views in your file that are not placed on sheets.

Instead, you can link them with the Sheet Number:

Category Sheets have a property under data.parameters.SHEET_NUMBER; there are also parameters for discipline and phase and other properties you might have set for the Project Explorer organisation.

Category Views also have a property data.parameters.VIEWPORT_SHEET_NUMBER along with many other standard and custom parameters that you may have set.

So, to list just Sheets, it will be as you have set in your question, but I’ve added some extra to focus the results :

query GetSheets($projectId: String!,
                $versionRefencedObjectId: String!, 
                $sheets_select: [String],
                $sheets_query: [JSONObject!]) {
  stream(id: $projectId) {
    object(id: $versionRefencedObjectId) {
      children(query: $sheets_query, select: $sheets_select) {
        objects {
          data
        }
      }
    }
  }
}

with variables:

{
  "projectId": "08068f03a5",
  "versionRefencedObjectId": "29921e44a3d85c294f10262ae290b570",
  "sheets_query": [
    {
      "field": "category",
      "operator": "=",
      "value": "Sheets"
    }
  ],
  "sheets_select": [
    "category",
    "parameters.SHEET_NUMBER.value",
    "parameters.SHEET_NAME.value"
  ]
 }

leading to:

But you had that already.

A views-appearing-on-sheets query would be:

query GetViews($projectId: String!, $views_select: [String], $versionRefencedObjectId: String!, $views_query: [JSONObject!]) {
  stream(id: $projectId) {
    object(id: $versionRefencedObjectId) {
      children(query: $views_query, select: $views_select) {
        objects {
          data
        }
      }
    }
  }
}

with variables:

{
  "projectId": "08068f03a5",
  "versionRefencedObjectId": "29921e44a3d85c294f10262ae290b570",
  "views_query": [
    {
      "field": "category",
      "operator": "=",
      "value": "Views"
    },
    {
      "field": "parameters.VIEWPORT_SHEET_NUMBER.value",
      "operator": "!=",
      "value": "void"
    }
  ],
  "views_select": [
    "category",
    "parameters.VIEW_FAMILY_SCHEDULES.value",
    "parameters.Unterdisziplin.value",
    "parameters.VIEWPORT_SHEET_NUMBER.value",
    "parameters.VIEW_DESCRIPTION.value",
    "parameters.PLAN_VIEW_LEVEL.value"
  ]
}

The field != void trick will filter out any view not placed on a sheet. The value void could equally be banana or an empty string "", but that’s just my habit of making the action explicit.

If, instead, you want to get Views for a specific sheet, you can pass the value of one of the Sheets captured earlier and change the operator to "="

"views_query": [
    {
      "field": "category",
      "operator": "=",
      "value": "Views"
    },
    {
      "field": "parameters.VIEWPORT_SHEET_NUMBER.value",
      "operator": "=",
      "value": "TGA-HZG-LPH 5-01"
    }
  ],

1 Like

If you really want to be fancy there are a few other niceties we can add to structure the query response.

Add a labelled count to the one in your original query. We can alias any individual data point

number_of_views: totalcount

Also with aliases we can label the response with the new speckle terminologies

 project: stream(id: $projectId) {
    version: object(id: $versionRefencedObjectId) {
      sheets: children(query: $sheets_query, select: $sheets_select, depth: 2) {
        number_of_sheets: totalCount

we can use aliases to also concatenate the queries for Sheets and Views into a single call:

query GetSheetsAndViews($projectId: String!, $sheets_select: [String], $views_select: [String], $versionRefencedObjectId: String!, $sheets_query: [JSONObject!], $views_query: [JSONObject!]) {
  project: stream(id: $projectId) {
    version: object(id: $versionRefencedObjectId) {
      sheets: children(query: $sheets_query, select: $sheets_select, depth: 2) {
        number_of_sheets: totalCount
        objects {
          data
        }
      }
      views: children(query: $views_query, select: $views_select, depth: 2) {
        number_of_views: totalCount
        objects {
          data
        }
      }
    }
  }
}

The variables will be a combination of those above.

And the response:

{
  "data": {
    "project": {
      "version": {
        "sheets": {
          "number_of_sheets": 19,
          "objects": [
            {
              "data": {
                "category": "Sheets",
                "parameters": {
                  "SHEET_NUMBER": {
                    "value": "TGA-HZG-LPH 5-01"
                  },
                  "SHEET_NAME": {
                    "value": "Heizung Hofgebäude Untergeschoss"
                  }
                },
                "id": "1285ca80f03dbb09bcd5565ac7503901"
              }
            },
            ... snip
          ]
        },
        "views": {
          "number_of_views": 115,
          "objects": [
            {
              "data": {
                "category": "Views",
                "parameters": {
                  "VIEW_FAMILY_SCHEDULES": {
                    "value": "Section"
                  },
                  "Unterdisziplin": {
                    "value": "Lüftung"
                  },
                  "VIEWPORT_SHEET_NUMBER": {
                    "value": "TGA-RLT-LPH 3-01"
                  },
                  "VIEW_DESCRIPTION": {
                    "value": "Ansicht RLT-Gerät"
                  },
                  "PLAN_VIEW_LEVEL": {
                    "value": null
                  }
                },
                "id": "03b60d8de0552e7f1d63a250d891974b"
              }
            },
            ... snip
          ]
        }
      }
    }
  }
}
1 Like

Wow, this is great and very powerfull! When comprehensive documentation with examples does not exist, this is worth gold! Alot can be learned from elaborative answer like this, not only about the asked question, but also about the API and GraphQL in general. So thank you, and keep on giving such great answers to the community!

2 Likes