Time Series
Every Metric can be visualized as a time series. Unlike counters, which return a single value for a time range, a time series returns values for every time granule over the requested time range. For example, a time series could represent
- Monthly sales for the quarter,
- Daily signups for the week, or
- Minute-by-minute error occurrences in the last hour.
Any time you need to visualize a change in Metric over time, consider using a time series. If one value will do, consider using a counter; otherwise, if you need a Metric broken down by Dimension and sorted, consider using a leaderboard.
Usage
When building customer-facing analytics, time series are essential for understanding how a Metric changes over time. Most customer dashboards are centered around a time series, and any additional visualizations use a time range derived from the time series.
There are lots of libraries you can use to visualize time series. We've chosen to use echarts-for-react in the example above, but Propel is compatible with all charting libraries. If you're using React and want some inspiration, check out our blog post, Best React Charting Libraries for Data Visualization and Analytics.
Arguments
You will pass a TimeSeriesInput
when querying the time series. The most
important arguments are
- The
timeRange
to query over, - The time
granularity
to aggregate by, and - The
filters
to use.
Read more about TimeSeriesInput
.
Returns
The query returns an array of labels
and an array of values
inside a
TimeSeriesResponse
. There is a label and value for every time granule of the
requested time range.
Each value is a number wrapped in a string. Using a string ensures we can support values greater than 32-bits in the GraphQL API.
Read more about TimeSeriesResponse
.
Example
Imagine we have a Data Pool syncing from a table of sales data. The sales data might look like the following:
We can create a Sum Metric named "sales" which sums up the sales data. By including "Salesperson" and "Product ID" as Dimensions, we can answer questions with our Metric. Follow along for worked examples.
1. How many sales did a salesperson make?
In order to answer the question, "How many sales did a salesperson make?",
we need to query our Sum Metric and filter by "Salesperson". In the GraphQL
query below, we use metricByName
to get the "sales" Metric, and then we pass
a variable, $salesperson
, to the filter.
- GraphQL Query
- GraphQL Variables
- JSON Response
query TimeSeriesExample1 (
$timeRange: RelativeTimeRange,
$granularity: TimeSeriesGranularity!,
$salesperson: String!
) {
sales: metricByName (uniqueName: "sales") {
timeSeries ({
timeRange: { relative: $timeRange }
granularity: $granularity
filters: [{
column: "Salesperson"
operator: EQUALS
value: $salesperson
}]
}) {
values
}
}
}
{
"timeRange": "THIS_YEAR",
"salesperson": "Mike"
}
{
"data": {
"sales": {
"timeSeries": {
"values": ["100", "200", "300", "400", "500", "600"]
}
}
}
}
2. How many times did we sell a particular product?
In order to answer the question, "How many times did we sell a particular product?",
we need to query our Sum Metric and filter by the "Product ID" Dimension. In the GraphQL
query below, we use metricByName
to get the "sales" Metric, and then we pass
a variable, $productId
, to the filter.
- GraphQL Query
- GraphQL Variables
- JSON Response
query TimeSeriesExample2 (
$timeRange: RelativeTimeRange,
$granularity: TimeSeriesGranularity!,
$productId: String!
) {
sales: metricByName (uniqueName: "sales") {
timeSeries ({
timeRange: { relative: $timeRange }
granularity: $granularity
filters: [{
column: "Product ID"
operator: EQUALS
value: $productId
}]
}) {
values
}
}
}
{
"timeRange": "THIS_YEAR",
"productId": "1001"
}
{
"data": {
"sales": {
"timeSeries": {
"values": ["100", "200", "300", "400", "500", "600"]
}
}
}
}