Skip to main content

View underlying data

BETA FEATURE

This is a Beta feature. The documentation and feature may change rapidly.

Introduction

View Underlying Data helps you quickly see “what makes up this number” at the most detailed level. By examining the details behind every data point, you can make more informed, data-driven decisions.

Holistics' View Underlying Data requires zero setup and lets you flexibly tailor the underlying data table to your needs.

Supported visualizations

  • Line, column, bar, area and combination charts
  • Pie, donut, pyramid and funnel charts
  • KPI
  • Table
  • Pivot table
  • Gauge chart

Who has access to this feature

Users with permission to explore the underlying dataset of a visualization — typically those with the Explorer, Analyst, or Admin roles — can use this feature.

This feature is not available to users accessing visualizations via shareable links, as they are limited to Viewer role.

Feature configurations (Coming soon)

In Holistics, you can configure the "View Underlying Data" feature as follows:

  • Customize detail views for a specific metric at dataset level or visualization level
  • Disable the feature for an entire dataset or a specific visualization

Customize detail views

Problem and solution

When you click "View Underlying Data," Holistics generates a default table. Sometimes, the default table may not include the most relevant fields, or it might include more fields than necessary for the analytical patterns your users expect.

For instance, a 'Revenue' metric might generate a large table with order ID, user ID, product ID, and all related information, without knowing the user's intended analysis.

To enhance the user experience, we’ve developed a feature that allows analysts to customize the underlying data table for each metric.

Each metric can have multiple detail views to provide various analytical perspectives, with preselected fields tailored to different needs.

Continue with the 'Revenue' metric example, now you can create multiple detail views:

  • List of Orders: order ID, order date, status
  • List of Users: user ID, full name, email, city
  • List of Products: product ID, product name, price

Before and after the customization:

How it works

Method

The configuration is currently done through code, with a GUI solution in development.

Configuration levels
  • You can customize the detail views for each metric either at the dataset level or the visualization level.
  • Dataset level: This configuration applies to all visualizations using that dataset
  • Visualization level: This configuration takes precedence over the dataset level, affecting only the specific visualization for which it is set
Pro tips
  • Use const to define reusable field lists for views. These can be utilized across various metrics and visualizations, enhancing consistency and efficiency.
  • Assign a meaningful label to each view to improve the end-user experience, making it clear and intuitive.
  • Arrange fields in the view according to the preferred order, as this will determine how they appear in the underlying table.
Code structure at dataset level

Detail views for metric 'Revenue' is defined under context > analysis > underlying_data

//Define reusable field lists
const order_details = [
r(order_master.order_id),
r(order_master.order_created_date),
r(ecommerce_users.full_name),
r(order_master.status),
r(ecommerce_products.name),
r(order_master.quantity),
r(order_master.price),
]

const user_details = [
r(ecommerce_users.id),
r(ecommerce_users.sign_up_date),
r(ecommerce_users.full_name),
r(ecommerce_users.gender),
r(ecommerce_users.age),
r(ecommerce_countries.name),
r(ecommerce_cities.name),
r(ecommerce_users.email),
]

const product_details = [
r(ecommerce_products.id),
r(ecommerce_products.name),
r(ecommerce_products.price),
]

//Dataset definition
Dataset ecommerce_demo {
__engine__: 'aql'
label: 'Ecommerce Demo'
description: 'All logic of our e-commerce platform'
data_source_name: 'postgres_test'

models: [
ecommerce_merchants,
ecommerce_products,
ecommerce_users,
ecommerce_countries,
ecommerce_cities,
ecommerce_categories,
order_master
,
]

relationships: [
relationship(order_master_ecommerce_merchants, true),
// relationship(order_master.user_id > ecommerce_orders.user_id, true),
relationship(order_master_ecommerce_products, true),
// relationship(ecommerce_products.id - ecommerce_product_images.product_id, true),
relationship(ecommerce_cities.country_code > ecommerce_countries.code, true)
,
relationship(ecommerce_products.category_id > ecommerce_categories.id, true)
,
relationship(order_master.user_id > ecommerce_users.id, true)
,
relationship(ecommerce_users.city_id > ecommerce_cities.id, true)
]
owner: '[email protected]'

metric revenue {
label: "Revenue"
type: "number"
hidden: false
description: "Revenue is total order value"
definition: @aql order_master.revenue;;
}

//Define context
context {
analysis {
underlying_data { //underlying_data is defined for each metric
metric revenue {
view list_of_orders {
label: 'List of Orders'
description: 'List of orders contributing to Revenue'
fields: order_details //reusing the field list order_details
}

view list_of_users {
label: 'List of Users'
description: 'List of users contributing to Revenue'
fields: user_details
}

view list_of_products {
label: 'List of Products'
description: 'List of products contributing to Revenue'
fields: product_details
}
}
}
}
}
}
Code structure at visualization level

Detail views for metric 'Revenue' is defined under context > analysis > underlying_data

block v23: VizBlock {
label: 'AOV overtime'
viz: LineChart {
dataset: ecommerce_demo
calculation aov {
label: 'Average Order Value'
formula: @aql order_master.revenue / order_master.count_distinct_users;;
calc_type: 'measure'
data_type: 'number'
}
x_axis: VizFieldFull {
ref: r(order_master.order_created_date)
transformation: 'datetrunc month'
format {
type: 'date'
pattern: 'LLL yyyy'
}
}
y_axis {
settings {
show_data_label_by: 'value'
}
series {
field: VizFieldFull {
ref: 'aov'
format {
type: 'number'
pattern: '#,###'
}
}
}
}
settings {
x_axis_show_null_datetime: false
aggregate_awareness {
enabled: true
debug_comments: true
}
}
context {
analysis {
underlying_data {
metric aov {
view aov_details {
label: 'Order details'
fields: [
r(order_master.order_id),
r(order_master.order_created_date),
r(order_master.status),
r(order_master.quantity),
r(order_master.price),
]
}
}
}
}
}
}
}

Disable the feature

Problem and solution

Holistics turns on View underlying data for every metric by default. However, sometimes you don’t want your users to access the detailed data, commonly in the case of embedded dashboards for external clients.

We’ve developed a feature that allows analysts to disable this feature at dataset level or visualization level.

How it works

Method

The configuration is currently done through code, with a GUI solution in development.

Configuration levels
  • View underlying data is always enabled by default.

  • You can disable the feature at dataset level or visualization level

  • Keep in mind that the most restrictive configuration applies. In other words, for "View Underlying Data" to be available in a visualization, it must be enabled at both levels. For example:

    Dataset levelVisualization levelFinal effect at the visualization level
    EnabledDisabledDisabled
    DisabledEnabledDisabled
Code structure at dataset level

The feature flag is defined under settings > analysis_interactions > view_underlying_data

Dataset ecommerce_demo_disabled_vud {
__engine__: 'aql'
label: 'Ecommerce - Disabled VUD'
description: 'All logic of our e-commerce platform. \nData from our **Databricks warehouse**'
data_source_name: 'postgres_test'

models: [
ecommerce_merchants,
ecommerce_products,
ecommerce_users,
ecommerce_countries,
ecommerce_categories,
ecommerce_cities,
order_master
,
]

relationships: [
relationship(order_master_ecommerce_merchants, true),
// relationship(order_master.user_id > ecommerce_orders.user_id, true),
relationship(order_master_ecommerce_products, true),
// relationship(ecommerce_products.id - ecommerce_product_images.product_id, true),
relationship(ecommerce_cities.country_code > ecommerce_countries.code, true)
,
relationship(ecommerce_products.category_id > ecommerce_categories.id, true)
,
relationship(order_master.user_id > ecommerce_users.id, true)
,
relationship(ecommerce_users.city_id > ecommerce_cities.id, true)
]
owner: '[email protected]'

metric revenue {
label: "Revenue"
type: "number"
hidden: false
description: "Revenue is total order value regardless of status"
definition: @aql order_master.revenue;;
}

metric count_distinct_user {
label: "CountD User"
type: "number"
hidden: false
description: "Number of users by distinct user_id"
definition: @aql order_master.count_distinct_users ;;

}

//Disable
settings {
analysis_interactions {
view_underlying_data {
enabled: false
}
}
}
}
Code structure and example at visualization level

The feature flag is defined under settings > analysis_interactions > view_underlying_data

block v_5wmj: VizBlock {
label: 'Monthly Revenue'
viz: CombinationChart {
dataset: ecommerce_demo
x_axis: VizFieldFull {
ref: r(order_master.order_created_date)
transformation: 'datetrunc month'
format {
type: 'date'
pattern: 'LLL yyyy'
}
}
y_axis {
settings {
show_data_label_by: 'value'
}
series {
mark_type: 'line'
field: VizFieldFull {
ref: 'revenue'
format {
type: 'number'
pattern: '#,###'
}
}
settings {
color: '#000004'
}
}
}
settings {
x_axis_show_null_datetime: false
aggregate_awareness {
enabled: true
debug_comments: true
}

analysis_interactions {
view_underlying_data {
enabled: false
}
}
}
}
}

Let us know what you think about this document :)