Make your own custom 'Datepicker' (Use/set your own timerange). Here is how to


Hi Everyone,

I created a custom Datepicker / Date-picker I would like to share with you.

It was a feature I was missing myself and made this kind of by coincidence, while I was testing out the ‘Dynamic Text’ plugin (Big thanks to the developers of this plugin).
I saw numerous people asking about something similar, so maybe this can help you on your way.

note: this not an official plugin in any way. Its just a creative workaround to select a timerange or date.


How it works (example 01) : range 1 month

datepicker_timepicker
The pop-up is just for this example to show you the input (this can be disabled)


Furthermore the 'Dynamic Text' plugin offers the option to use and specify what fields and data from you datasource you use. Additionally you can use custom JavaScript + the option to apply custom CSS styling. Furthermore you can use this in combination with '**onclick()**' events where the magic happens ;-)

With this date-picker you can quickly select a calendar day/custom time range and the dashboard will change and show data from that specific range.


Date/Timerange

Grafana is based on a ‘From’ and ‘To’ Time-range (So even if you want to change the date-picker only to ‘1’ specific day you will always need to specify a 2 ranges ‘from’ and ‘to’)

Date start 'From': 01-08-2023 start_time
Date end   'To'  : 01-08-2023 end_time

But with the correct styling a user will only see 1 ‘date’

Example 02 : Time-range 1 day

datepicker_timepicker_select_1day_only



Extra info:

For this example I will show how to make a picker for a full month.
I use a table (with static values) from GoogleSheet that I use as my Datasource,
but this can also be achieved with other Datasources.

How to set this up, check out the link below.
Link: https://youtu.be/GnWZsHjM5To

(I can confirm this also works for ‘influxDb’ which im using myself but requires extra steps for extracting date etc…)

My example table:



For this you will need to :

  1. Install the ‘Dynamic Text’ plugin

  2. Set GF_PANELS_DISABLE_SANITIZE_HTML to 'true' in the Grafana configuration (grafana.ini)

    - GF_PANELS_DISABLE_SANITIZE_HTML=true

    On how to disable Sanatizing read more here :
    Content | Volkov Labs

  3. A query/table that contains one or two column(s) with a ‘start’ and ‘end’ DATE/RANGE (depending what you want to achieve)

The format used by Grafana for setting the range "from" and "to" is as
follow "2023-08-01T00:00:00" == "YYYY-MM-DD + T + HH:MM:SS"

Note: For the people from Europe the date Grafana is using is specified the
other way around! so YEAR comes first, then MONTH, then DAY ;-)

As for the the ‘start’ and ‘end’ TIME this will be explained later in this post.

ps. I did not take [T]imezone into consideration in this example. But changing the range will work even with out that.


Follow the steps from below to create buttons filled/linked with data from your datasource.

Step 1) Add a -new- visualization panel.

Step 2) Change/select ‘Dynamic Text’ plugin

Step 3) Scroll down until you see the section ‘DYNAMIC TEXT’

Step 3a) Change render template to ‘All rows’

Step 3b) Add ‘Styles’ & ‘Javascript Code’ to section
“Select Editors to display. Editors with updated values always displayed”

Step 4) Editor (Optional: change to your likings)
Im using setting ‘HTML’ and formatting to ‘Auto’

Step 5) In the ‘CONTENT’ section
Copy/paste the code from below.

{{#each data}}  
{{/each}}

This is the base to show ALL rows from your table. This works like the .forEach() from JavaScript.
But only using this code will give you an ‘empty’ result. Because we haven’s specified what data to retrieve/grep yet.

If you want to use data from just a specific row read more on how to use this here :

Or watch Youtube video (min 3:05 to 3:55)

Step 5a) Specify what data you would like to grep/use
For this you need to specify one or more headers {{header field here}} from your datasource/table

To grep values from columns 'DateRangeFrom' and 'DateRangeTo' for each
row from the example table above use double curly braces '{{header field here}}'
So it would be '{{DateRangeFrom}}' and '{{DateRangeTo}}'

In ‘CONTENT’ section copy/paste one of the examples below

Example 01

{{#each data}}  
<div>{{DateRangeFrom}}  to  {{DateRangeTo}}</div>
{{/each}}

Example 02

{{#each data}}  
<div>{{Monthname}}	</div>
{{/each}}
Expected result here		 

Example 01  				  Or 	Example 02
		
2023-01-01 to 2023-01-31			Januari
2023-02-01 to 2023-02-28			Februari
2023-03-01 to 2023-03-31			March
2023-04-01 to 2023-04-30			April
2023-05-01 to 2023-05-31			May
2023-06-01 to 2023-06-30			June
2023-07-01 to 2023-07-31			July
2023-08-01 to 2023-08-31			August
2023-09-01 to 2023-09-30			September
2023-10-01 to 2023-10-31			October
2023-11-01 to 2023-11-30			November
2023-12-01 to 2023-12-31			December

*note: for now this is still plain text, cause we haven’t added any styling or event triggers


Step 5b) Like a website you can also add CSS styling by adding/specifying a class to an element. Scroll down to the section ‘CSS Styles’ to do so

You can use the following CSS/code as an example
		
 .button {
 padding: 4px 10px;
 text-align: center;
 text-decoration: none;
 display: inline-block;
 font-size: 15px;
 letter-spacing: 0.5px;
 margin: 4px 2px;
 transition-duration: 0.6s;
 cursor: pointer;
 border-radius: 10px; 
 background-color: #fcfcfc;
 color: black; 
 border: 2px solid lightgrey;
 }

And change the ‘CONTENT’ to code

<p>
{{#each data}}
<div class="button" type="button")">from '{{DateRangeFrom}}' to '{{DateRangeTo}}'</div>
{{/each}}

the result will be:


Step 6) Add ‘onclick’ event and change the Dashboard timerange ‘FROM’ and ‘TO’

For this I use 3 things.

  1. An ‘onclick’ event to <div> element
    (In simple terms > When you click on the button → trigger this event and execute JavaScript code)
  2. The JavaScript code that changes the timerange of the Dashboard after selecting/pressing the button
  3. Set the ‘start’ and ‘end’ TIME of the select range (You do this in the Javascript part)

Step 6.1) Go to section ‘CONTENT’ again add the ‘onclick()’ part to your code.

<p>
{{#each data}}
<div class="button" type="button" onclick="changeToSelectedRange('{{DateRangeFrom}}','{{DateRangeTo}}')">from '{{DateRangeFrom}}' to '{{DateRangeTo}}'</div>
{{/each}}


Step 6.2) Go to ‘Javascript Code’ and copy/paste code from below


  changeToSelectedRange = (range_start, range_end) => {
  
  let timeStart = "T00:00:00"; //<<-- Change 'start' time here of the range
  let timeEnd = "T23:59:59";   //<<-- Change 'end' time of the range
  let rangeStart_merged = range_start + timeStart;
  let rangeEnd_merged = range_end + timeEnd;

  //<<-- get an alert pop-up (for testing output)
  //alert("\n" + "Range start : " + rangeStart_merged + "\n\n" + "Range end : " + rangeEnd_merged); 

  //Two lines below are responsible to change the actual timerange changeof the dashboard
  timeSrv = angular.element('grafana-app').injector().get('timeSrv'); 
  timeSrv.setTime({ from: rangeStart_merged, to: rangeEnd_merged }); 

  return;
}


Step 6.3) Set ‘start’ and ‘end’ TIME in the JavaScript code you just copy/pasted

  let timeStart = "T00:00:00"; 
  let timeEnd = "T23:59:59"; 
		
  Change the time in the lines above if you prefer different selection
  of start en end time.


Step 7) The use of extra data to show (optional)
For the most basic ‘Datepicker’ you will only need two columns '{{DateRangeFrom}}' '{{DateRangeTo}}'

As you might notice in my example table I used some extra columns.

This data can be used as additional {{variable}} text to add to your buttons.

As mentioned at step ‘5a’ you will grep/iterate data for each row.
Depending on what other {{column headers}} you specify, this can be used/shown inside
the button we just created earlier.


To create buttons like the example below use the following code :

Copy/paste this in ‘CONTENT


{{#each data}}
<div class="button" type="button" onclick="changeToSelectedRange('{{DateRangeFrom}}','{{DateRangeTo}}')">
  <b>{{MonthName}} {{Year}}</b><br>(01 - {{MonthDayLast}} {{MonthNameShort}})
</div>
{{/each}}


For the rest you can you use any regular text as well as < HTML > code in the CONTENT section to style your button/view as you please




If everything is correct you should have your own custom styled Datepicker now!

Hope this helps.

Cheers

1 Like

@orosolido That is cool! Thank you for sharing.

It’s incredible to see how the community has utilized CSS and JavaScript features in so many ways.

We’re currently creating a new video tutorial for the Dynamic Text panel, and we would love to feature your solution in it.

@mikhailvolkov thank you! Happy to share it.

The ability to use CSS and JS is a great addition for Grafana and creates a lot of new possibilities for stuff like this. I will do a similar post in one of the upcoming days for users who have ‘influxDb’ as DataSource.

As for the new video tutorial :+1:

Possible to share the link with me when it comes online?

2 Likes

@orosolido I will. You can also subscribe and watch the premier with us, which is tentative next week.

1 Like

this is awesome @orosolido !!!

Thank you @mattabrams :slightly_smiling_face:

Awesome!!!

Also coming to a theatre near you soon, with Dynamic Text you can bring in bootstrap and get something like this

You can create a similar time picker with Data Manipulation Panel and update the location service’s time range.

There are three proposed options so far. Any other options?

@moderator : Is there a way for me to edit/add something to my original post?
For some reason I don’t see that option anymore.

@orosolido @yosiasz Yours and other community use cases showcased in the latest video

2 Likes