Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Table of Contents

Introduction

OpenSpecimen allows to configure graphical dashboards with various counters and graphs. This helps users to get a summary view of the data collected for the protocol. A default dashboard is shipped with OpenSpecimen which is set for all protocols. But users can change this to update the dashlets as per requirement. Dashboard feature is available as an enterprise plugin.

Default dashboard

When OpenSpecimen is deployed with dashboard plugin, all protocols are set with a default dashboard with below elements

Table of Contents

Introduction

OpenSpecimen allows configuring graphical dashboards with various counters and graphs. This helps users to get a summary view of the data collected for the protocol. A default dashboard is shipped with OpenSpecimen which is set for all protocols. But users can change this to update the dashlets as per requirement. Dashboard feature is available as an enterprise plugin.

Default dashboard

When OpenSpecimen is deployed with dashboard plugin, all protocols are set with a default dashboard with the below elements:

  1. Metrics(Counts)
    1. Total participants
    2. Total primary specimens
    3. Total available specimens
    4. Total distributed specimens
  2. Graphs
    1. Specimens by type
    2. Specimens by anatomic site
    3. Specimens collected vs distributed in previous quarter
    4. Specimens stored by freezer

Creating dashlets

Each of the above elements - metrics and graphs are considered as dashlets. These dashlets can either be created using query interface or REST API.

Create dashlet via UI

For details on creating using query interface, refer to Dashboard changes using query.

Create dashlet via API

URL: http[s]:<host>:<port>/openspecimen/rest/ng/dashlet-configs

...

Dashlet to include metric : Count of completed visits

...

    1. previous quarter
    2. Specimens stored by freezer

Creating dashlets

Each of the above elements - metrics and graphs are considered as dashlets. These dashlets can either be created using query interface or REST API.

Create dashlet via UI

For details on creating using query interface, refer to Dashboard changes using query.

Create dashlet via API

URL: http[s]:<host>:<port>/openspecimen/rest/ng/dashlet-configs

URL
MethodPOST
Requestapplication/json
Example 1 JSON for Metric

Dashlet to include metric : Count of completed visits

Code Block
{
	"name":"visit_count",
	"title":"Visits",
    "type":"COUNTER",
	"dataSource":{
		"options":{
			"criteria":" SpecimenCollectionGroup.activityStatus = \"Active\" and  SpecimenCollectionGroup.collectionStatus = \"Complete\" and  Specimen.collectionStatus = \"Collected\"  ",
			"metric":{
				"expr":"count(distinct SpecimenCollectionGroup.name)",
				"title":"Visits"
			}
		},
		"type":"AQL"
	},
	"chartOpts":{},
	"activityStatus":"Active"
}


Example 2 JSON for graph

Dashlet to include graph: Available aliquots by type

Code Block
  {
    "name": "dash_1_20161215_0251537",
    "title": "Available aliquots by type",
    "type": "
COUNTER",
CHART",
    "dataSource": {

      "options": {
        "criteria": " 
SpecimenCollectionGroup
Specimen.
activityStatus
collectionStatus = \"
Active
Collected\" and  
SpecimenCollectionGroup
Specimen.
collectionStatus
lineage = \"
Complete
Aliquot\" and  Specimen.specimenPosition.
collectionStatus
containerName 
=
exists 
\"Collected\"
  ",

        "metric": {

          "expr": "count(distinct 
SpecimenCollectionGroup
Specimen.
name
id)",

          "title": "
Visits
Aliquots"
} }, "type":"AQL" }, "chartOpts":{}, "activityStatus":"Active" }Example json for graph

Dashlet to include graph : Available aliquots by type

Code Block {
        },
        "category": {
          "expr": "Specimen.type",
          "
name
title": "
dash_1_20161215_0251537"
Type"
        }
      },
      "
title
type": "AQL"
Available

  
aliquots
 
by
 
type"
},
    "chartOpts": {"type
": "CHART"
":"Pie","showSectionValuePct":true},
    "
dataSource
activityStatus": 
{ "options": { "criteria": " Specimen.collectionStatus = \"Collected\" and Specimen.lineage = \"Aliquot\" and Specimen.specimenPosition.containerName exists ", "metric": { "expr": "count(distinct Specimen.id)",
"Active"
  }


  1. name: unique name to identify the dashlet
  2. title: caption to display on chart or counter
  3. type: specifies whether the dashlet represents a counter or chart
  4. datasource: specifies how the data required for rendering the dashlet should be queried
    1. type: specifies the data source type. At present, AQL and SQL data sources are supported out of the box
    2. options: varies according to the chosen data source.
      1. criteria: specifies the condition on the records to be used for displaying counter or chart.
      2. category: specifies the field to categorise the records. In above example, records are categorised based on specimen type field
      3. metric: specifies the counter value or category value
      4. expr: Any valid temporal expression
      5. title: category or metric caption
  5. chartOpts: type of dashlet chart to display
Example 3 JSON for graph

Dashlet to include graph: Count of participants by specimen type

Code Block
{
  "name" : "dash_4973_20201023_1242657",
  "title" : "
Aliquots"
Count of participants by 
}
specimen type",
  "type" : 
"CHART",
  "
category
dataSource" : {

    
"
expr
options" : 
"Specimen.type",
{
      "criteria" : "Participant.vitalStatus in (\"
title": "Type" } }, "type": "AQL" }, "chartOpts": {
Alive\",\"Dead\") and  Specimen.type any  and  Specimen.type exists  and  CollectionProtocol.Title in (\"Test_CP_1\",\"Test_CP_2\",\"Test_CP_3\",\"Kidney Disease\")",
      "metric" : {
        "
type
expr" : "
Pie" }
count(distinct Participant.participantId)",
    
"activityStatus":
 
"Active"
   
}
  1. name: unique name to identify the dashlet
  2. title: caption to display on chart or counter
  3. type: specifies whether the dashlet represents a counter or chart
  4. datasource: specifies how the data required for rendering the dashlet should be queried
    1. type: specifies the data source type. At present, AQL and SQL data sources are supported out of the box
    2. options: varies according to the chosen data source.
      1. criteria: specifies the condition on the records to be used for displaying counter or chart.
      2. category: specifies the field to categorise the records. In above example, records are categorised based on specimen type field
      3. metric: specifies the counter value or category value
      4. expr: Any valid temporal expression
      5. title: category or metric caption
  5. chartOpts: type of dashlet chart to display
Example
"title" : "Participants"
      },
      "category" : {
        "expr" : "Specimen.type",
        "title" : "Specimen Type"
      }
    },
    "type" : "AQL"
  },
  "chartOpts": {"type":"Pie", "showLegendValuePct" : true},
  "activityStatus": "Active"
}


Example 4 JSON for SQL based count dashlet


Code Block
  {
    "name": "dash-sys-active-dps",
    "title": "Distribution Protocols",
    "type": "COUNTER",
    "dataSource": {
      "type":"SQL", 
      "options": {
        "metrics": [{"columnIndex": 0,"title": "Active Distribution Protocols"}],  
        "sql": "select count(dp.identifier) from catissue_distribution_protocol dp  where dp.activity_status = 'Active'"
      }
    },
    "chartOpts": {},
    "activityStatus": "Active"
  }


Example 5 JSON for SQL based graph dashlet


Code Block
{
    "name": "specimensByAnatomicSiteGroup",
    "title": "Collected specimens by anatomic site group",
    "type": "CHART",
    "dataSource": {
      "type":"SQL",
      "options": {
        "category": {"columnIndex":0,"title":"Anatomic Site"},
        "metrics":[{"columnIndex":1,"title":"Collected Specimens"}],
        "sql": "select a.value, count(s.identifier) from catissue_specimen s inner join catissue_collection_protocol cp on cp.identifier = s.collection_protocol_id inner join catissue_permissible_value pv on pv.value = s.tissue_site inner join os_pvs_hierarchy h on h.descendant_id = pv.identifier inner join catissue_permissible_value a on a.identifier = h.ancestor_id where %sql_cp_restriction% and (a.parent_identifier is null and s.collection_status = 'Collected' and s.lineage = 'Aliquot' and s.available_quantity > 0 and pv.public_id = 'anatomic_site' and a.public_id = 'anatomic_site' and s.activity_status != 'Disabled') group by a.value order by count(s.identifier) desc",
        "restrictionOpts":{"type":"sql_cp_restriction","opts":{"cpIdExpr":"cp.identifier"}} 
      } 
    },
    "chartOpts": {"type":"Pie
","showSectionValuePct":true}, "activityStatus": "Active" }columnIndex in category and metrics specify what column of SQL result set should be used. In above example, first column of result set (i.e. columnIndex: 0) is used to create categories and second column of result set is used to show the count of each category.
","showSectionValuePct":true},
    "activityStatus": "Active"
  }


columnIndex in category and metrics specify what column of SQL result set should be used. In above example, first column of result set (i.e. columnIndex: 0) is used to create categories and second column of result set is used to show the count of each category.


Info

To edit existing dashlets, use 'Get' method to get the dashlets. Edit the JSON code for the specific dashlet section and use 'Put' to update it.

When 'showSectionValuePct' is set to true like Example 2 above, it shows the percent of each section. See below graph:

Image Added

When 'showLegendValuePct' is set to true like Example 3 above, it shows the percent of each section in the legends. See below graph:

Image Added

Configuring dashboards to CP

...

URLhttp://<host>:<port>/openspecimen/rest/ng/dashboards/{dashboardId}
MethodPUT
Requestapplication/json
Example json


Code Block
{
  "view": "CollectionProtocol",
  "viewParams": {
    "cpId": "-1"
  },
  "dashlets": [
    {
      "config": {
        "name": "dash-sys-participants"
      },
      "sortOrder": 1
    },
    {
      "config": {
        "name": "visit_count"
      },
      "sortOrder": 2
    },
    {
      "config": {
        "name": "dash_1_20161214_0406950"
      },
      "sortOrder": 3
    },
    {
      "config": {
        "name": "dash_1_20161214_0357273"
      },
      "sortOrder": 4
    },
    {
      "config": {
        "name": "dash_1_20161215_0251537"
      },
      "sortOrder": 5
    },
    {
      "config": {
        "name": "dash-spmns-by-anatomic"
      },
      "sortOrder": 6
    },
    {
      "config": {
        "name": "dash-sys-coll-dist"
      },
      "sortOrder": 7
    },
{
      "config": {
        "name": "dash-sys-coll-dist-yr"
      },
      "sortOrder": 8
    },
    {
      "config": {
        "name": "dash-spmns-by-path"
      },
      "sortOrder": 9
    }
  ],
  "activityStatus": "Active"
}


...