Dashboards & Visualizations

Using a timechart to set earliest and latest global_time values in dashboard studio

datachacha
Explorer

Hi, 

I am having an issue trying to make a version of the search app filtering timeline work in my dashboard in Dashboard Studio with other visualizations. I have set a token interaction on click to update the global_time.earliest value as to the time that is clicked on the chart. I, however, am running into an issue where I cannot set the global_time.latest value by clicking again on the timechart. If I set up a second token interaction to get the latest time, it just sets it to the same as the earliest, all on the first click. I'm trying to filter it down to each bar's representation on the timechart, which is 2 hours ( |timechart span=2h ...). 

Like the search apps version, this timechart is meant to be a filtering tool that will only filter down the search times of the other visualizations once it is set. Setting the earliest token works perfectly fine; it's all just about the latest. I just need to know how or if it is possible.

Thank you!!

Labels (3)
0 Karma

livehybrid
SplunkTrust
SplunkTrust

Okay @datachacha 

Ive been having a good think about this and I dont think I have an elegant solution - but I think I do have *a* solution:

livehybrid_0-1750698390194.png

This uses a hidden token/text box to the side and a search to determine the _time+2hours. 

You can then use this in your other queries as earliest/latest as per the sample event on the dashboard using `$globalTimeSpl:results.earliest$` and `$globalTimeSpl:results.latest$`

Here is the full JSON to have a play around with - does this do what you need?

{
    "title": "testing",
    "description": "",
    "inputs": {
        "input_MPUmpGoR": {
            "options": {
                "defaultValue": "DEFAULT",
                "token": "calc_earliest"
            },
            "title": "Earliest",
            "type": "input.text"
        },
        "input_zIorjrMc": {
            "options": {
                "defaultValue": "-24h@h,now",
                "token": "tr_global"
            },
            "title": "Main Time Selector",
            "type": "input.timerange"
        }
    },
    "defaults": {
        "dataSources": {
            "ds.search": {
                "options": {
                    "queryParameters": {
                        "earliest": "-24h@h",
                        "latest": "now"
                    }
                }
            }
        }
    },
    "visualizations": {
        "viz_BcDlqy4I": {
            "options": {
                "markdown": "Earliest = $globalTimeSpl:result.earliest$  \nLatest = $globalTimeSpl:result.latest$"
            },
            "type": "splunk.markdown"
        },
        "viz_NgmH6lHI": {
            "dataSources": {
                "primary": "ds_BlYVOfBA"
            },
            "title": "This shows for time selected + 2hours",
            "type": "splunk.table"
        },
        "viz_Nqdf4h2p": {
            "dataSources": {
                "primary": "ds_ccCiW2S8"
            },
            "eventHandlers": [
                {
                    "options": {
                        "tokens": [
                            {
                                "key": "row._time.value",
                                "token": "calc_earliest"
                            }
                        ]
                    },
                    "type": "drilldown.setToken"
                }
            ],
            "type": "splunk.column"
        },
        "viz_zUx2Zt29": {
            "dataSources": {
                "primary": "ds_ZKBDXZy2_ds_BlYVOfBA"
            },
            "type": "splunk.table"
        }
    },
    "dataSources": {
        "ds_BlYVOfBA": {
            "name": "global",
            "options": {
                "query": "index=_internal earliest=$globalTimeSpl:result.earliest$ latest=$globalTimeSpl:result.latest$ \n| addinfo \n| head 1\n|  table info* _raw"
            },
            "type": "ds.search"
        },
        "ds_ZKBDXZy2_ds_BlYVOfBA": {
            "name": "globalTimeSpl",
            "options": {
                "enableSmartSources": true,
                "query": "| makeresults \n| addinfo\n|  eval earliest=IF($calc_earliest|s$!=\"DEFAULT\",$calc_earliest|s$,info_min_time)\n|  eval latest=IF($calc_earliest|s$!=\"DEFAULT\",$calc_earliest$+7200, info_max_time)",
                "queryParameters": {
                    "earliest": "$tr_global.earliest$",
                    "latest": "$tr_global.latest$"
                }
            },
            "type": "ds.search"
        },
        "ds_ccCiW2S8": {
            "name": "tstat",
            "options": {
                "query": "| tstats count where index=_internal by _time span=1h",
                "queryParameters": {
                    "earliest": "$tr_global.earliest$",
                    "latest": "$tr_global.latest$"
                }
            },
            "type": "ds.search"
        },
        "ds_rt307Czb": {
            "name": "timeSPL",
            "options": {
                "enableSmartSources": true,
                "query": "| makeresults \n| addinfo",
                "queryParameters": {
                    "earliest": "-60m@m",
                    "latest": "now"
                }
            },
            "type": "ds.search"
        }
    },
    "layout": {
        "globalInputs": [
            "input_zIorjrMc"
        ],
        "layoutDefinitions": {
            "layout_1": {
                "options": {
                    "display": "auto",
                    "height": 960,
                    "width": 1440
                },
                "structure": [
                    {
                        "item": "viz_Nqdf4h2p",
                        "position": {
                            "h": 300,
                            "w": 1390,
                            "x": 10,
                            "y": 210
                        },
                        "type": "block"
                    },
                    {
                        "item": "viz_NgmH6lHI",
                        "position": {
                            "h": 140,
                            "w": 1390,
                            "x": 10,
                            "y": 60
                        },
                        "type": "block"
                    },
                    {
                        "item": "viz_BcDlqy4I",
                        "position": {
                            "h": 50,
                            "w": 300,
                            "x": 20,
                            "y": 10
                        },
                        "type": "block"
                    },
                    {
                        "item": "input_MPUmpGoR",
                        "position": {
                            "h": 82,
                            "w": 198,
                            "x": 1470,
                            "y": 50
                        },
                        "type": "input"
                    },
                    {
                        "item": "viz_zUx2Zt29",
                        "position": {
                            "h": 100,
                            "w": 680,
                            "x": 1470,
                            "y": 130
                        },
                        "type": "block"
                    }
                ],
                "type": "absolute"
            }
        },
        "tabs": {
            "items": [
                {
                    "label": "New tab",
                    "layoutId": "layout_1"
                }
            ]
        }
    }
}

🌟 Did this answer help you? If so, please consider:

  • Adding karma to show it was useful
  • Marking it as the solution if it resolved your issue
  • Commenting if you need any clarification

Your feedback encourages the volunteers in this community to continue contributing

datachacha
Explorer

Thank you for the timely response. I tried what you recommended and ran into a few issues that I was not able to diagnose or fix with the troubleshooting tips provided. 
I got everything looking exactly as you said. However, $result._time$ doesn't seem to evaluate to a time whatsoever; when I check the value, it is literally just "$result._time$".  The latest time value gets set to "relative_time(-7d@h", which appears incomplete as shown.
I get an error on the visualization saying Invalid earliest_time, and both earliest and latest show invalid values.
When I tried to put in the troubleshooting eval command you recommended, it did not fix the issue. The time should be coming in correctly.

0 Karma

datachacha
Explorer

@livehybrid

Thank you very much for this solution however my needs need to have it as streamlined as possible. While this does give the essential functionality that I need, it is a solution I need to work off of additionally. My needs specifically are that it is all click based and you don't have to change anything anywhere else and that it can all be handled within the timechart/bar chart. Anything else is to be fully hidden away.

Much like the search app counterpart I also needed the timechart to the update itself based on the time range the rest of the visualization would use. Ideally this would just zoom in on one bar. Unfortunately what I am trying to and what I am trying to make altogether can't have the Text box and specific manual inputs.

Simply put, this does accomplish the goal of setting time earliest and latest values that are 2h apart and then the other visualizations can take those tokens as their time. But I need a different approach to getting there.  

0 Karma

LAME-Creations
Path Finder
In Dashboard Studio, a single click interaction on the timechart can set both global_time.earliest (the start of the clicked bar) and global_time.latest (the end of the 2-hour bar) by using a token formula. Instead of relying on a second click, you’ll compute global_time.latest as global_time.earliest + 2 hours. This ensures the exact 2-hour range is applied to other visualizations, mimicking the Search app’s timeline filtering.

This is assuming that you want 2 hour chunks.  You can get crazy and tokenize the span=2h and then use that same token in the example I provide, but that is not the solution I am providing below.   

Steps to Implement
  1. Verify Your Timechart Configuration:
    • Ensure your timechart uses a 2-hour span, as you mentioned (| timechart span=2h ...). This means each bar represents a 2-hour bucket (e.g., 10:00–12:00, 12:00–14:00).
    • In Dashboard Studio, confirm the visualization is set up as a Timechart (Area, Column, or Line) under the Visualization tab.
  2. Set the global_time.earliest Token:
    • You’ve already set a token interaction for global_time.earliest, but let’s confirm it’s correct.
    • In Dashboard Studio’s UI Editor:
      • Select your timechart visualization.
      • Go to the Interactions tab in the configuration panel.
      • Under On Click, add a Set Token action:
        • Token Name: global_time.earliest
        • Token Value: $result._time$ (this captures the start time of the clicked bar, e.g., 10:00 for a 10:00–12:00 bar).
    • This sets global_time.earliest to the timestamp of the clicked bar’s start.
  3. Calculate global_time.latest Token:
    • Instead of a second click, compute global_time.latest as global_time.earliest + 2 hours using a token formula.
    • In the UI Editor:
      • Go to the same On Click interaction for the timechart.
      • Add a second Set Token action (below the global_time.earliest one):
        • Token Name: global_time.latest
        • Token Value: relative_time($global_time.earliest$, "+2h")
          • This uses Splunk’s relative_time function to add 2 hours to the earliest timestamp (e.g., if earliest is 10:00, latest becomes 12:00).
    • Both tokens will now be set on a single click, defining the exact 2-hour range of the clicked bar.
  4. Apply Tokens to Other Visualizations:
    • Ensure other visualizations in your dashboard use the global_time.earliest and global_time.latest tokens to filter their time ranges.
    • For each visualization (e.g., table, chart):
      • Go to the Search tab in the configuration panel.
      • Set the Time Range to Custom and use:
        • Earliest: $global_time.earliest$
        • Latest: $global_time.latest$
    • Alternatively, modify the search query directly to include the token-based time range, e.g.:
      spl
       
      index=your_index earliest=$global_time.earliest$ latest=$global_time.latest$ | ...
  5. Add a Default Time Range (Optional):
    • To prevent visualizations from breaking before a timechart click, set default values for the tokens.
    • In the UI Editor:
      • Go to the Dashboard configuration (top-level settings).
      • Under Tokens, add:
        • Token Name: global_time.earliest, Default Value: -24h@h (e.g., last 24 hours, snapped to hour).
        • Token Name: global_time.latest, Default Value: now (current time).
      • This ensures other visualizations display data until the timechart is clicked.
  6. Test the Dashboard:
    • Save and preview the dashboard.
    • Click a timechart bar (e.g., representing 10:00–12:00). Verify that:
      • global_time.earliest is set to the bar’s start (e.g., 10:00).
      • global_time.latest is set to the bar’s end (e.g., 12:00).
      • Other visualizations update to show data only for that 2-hour range.
    • Use the Inspect tool (click the three dots on a visualization > Inspect > Tokens) to debug token values if needed.
Why This Works
  • Single Click: Using relative_time($global_time.earliest$, "+2h") avoids the need for a second click, as it calculates the end of the 2-hour bar based on the clicked time.
  • Mimics Search App: The Search app’s timeline sets both earliest and latest times for a selected range. This solution replicates that by defining the full 2-hour bucket.
  • Dashboard Studio Limitation: Dashboard Studio doesn’t natively support range selection (like dragging over a timeline), so computing latest via a formula is the best approach.
Troubleshooting Tips
  • Tokens Not Setting: If global_time.latest isn’t updating, check the token syntax in the Source view (JSON). Ensure the relative_time function is correct: "value": "relative_time($global_time.earliest$, \"+2h\")".
  • Time Format Issues: Ensure $result._time$ returns a timestamp in epoch format (seconds). If not, use strptime in the timechart search to format it, e.g., | eval _time=strptime(_time, "%Y-%m-%d %H:%M:%S").
  • Visualization Not Updating: Confirm other visualizations reference $global_time.earliest$ and $global_time.latest$ correctly. Check their search queries in the Source view.
  • Span Mismatch: If the timechart span changes (e.g., dynamically set), you may need to make the +2h offset dynamic. Let us know if your span varies for a custom solution.
Example JSON Snippet (Source View)
For reference, here’s how the timechart’s interaction might look in the dashboard’s JSON (edit in Source view if needed):
json
 
{
  "visualizations": {
    "viz_timechart": {
      "type": "splunk.timechart",
      "options": { ... },
      "dataSources": {
        "primary": "ds_timechart"
      },
      "eventHandlers": [
        {
          "type": "drilldown.setToken",
          "options": {
            "token": "global_time.earliest",
            "value": "$result._time$"
          }
        },
        {
          "type": "drilldown.setToken",
          "options": {
            "token": "global_time.latest",
            "value": "relative_time($global_time.earliest$, \"+2h\")"
          }
        }
      ]
    }
  }
}

livehybrid
SplunkTrust
SplunkTrust

Hi @LAME-Creations 

Please can you confirm if you were able to test and have working the example and process provided? 

Unfortunately this reads a lot like an AI hallucination because it looks to mix Classic XML and Dashboard Studio approaches to tokens. For example it is not possible to put $ into the value field for a token, and it should be row._time.value not $result._time$

If you have this as a working approach then please can you share a working version as I wasnt aware it was possible to do evals in drilldown.setToken

🌟 Did this answer help you? If so, please consider:

  • Adding karma to show it was useful
  • Marking it as the solution if it resolved your issue
  • Commenting if you need any clarification

Your feedback encourages the volunteers in this community to continue contributing

datachacha
Explorer

Ok, thank you. I thought there was something up with the $'s; they would accept it as a static value instead of a predefined token when setting them up in the interactions menu, but the logic wouldn't work. And it seems to be the case as well for the second, the eval statement just did not work at all as intended.
I was wondering why this didn't work.

0 Karma
Career Survey
First 500 qualified respondents will receive a $20 gift card! Tell us about your professional Splunk journey.

Can’t make it to .conf25? Join us online!

Get Updates on the Splunk Community!

Can’t Make It to Boston? Stream .conf25 and Learn with Haya Husain

Boston may be buzzing this September with Splunk University and .conf25, but you don’t have to pack a bag to ...

Splunk Lantern’s Guide to The Most Popular .conf25 Sessions

Splunk Lantern is a Splunk customer success center that provides advice from Splunk experts on valuable data ...

Unlock What’s Next: The Splunk Cloud Platform at .conf25

In just a few days, Boston will be buzzing as the Splunk team and thousands of community members come together ...