Control Grafana time scale

Hello,
I’m trying to control the time scale of my Grafana plots into HabPanel using different buttons for 1h,1d,1w and so on, but I don’t know how to pass a variable to the iframe. For now my code looks like that:

<div ng-init="from_time='now-1h'"/> 
<div ng-init="to_time='now'"/>
    <table>
    	<tr>
        <th> <button type="button">1h</button></th>
        <th> <button type="button">1d</button></th>
        <th> <button type="button">1w</button></th>
        <th> <button type="button">1m</button></th>
        <th> <button type="button">6m</button></th>
      </tr>
    </table>

    <iframe src="http://192.168.0.165:3000/dashboard-solo/db/home?orgId=1&ng-from={{from_time}}&to=now&refresh=1m&panelId=1" width="450" height="200" frameborder="0"></iframe>

but it doesn’t work. The {{from_time}} variable is not read in the iframe. Do you know how to get iframe to read my variables?

This is actually disallowed by Angular, if you check the Javascript console it contains a link to https://docs.angularjs.org/error/$interpolate/noconcat?p0=http:%2F%2F192.168.0.165:3000%2Fdashboard-solo%2Fdb%2Fhome%3ForgId%3D1%26ng-from%3D{{from_time}}%26to%3Dnow%26refresh%3D1m%26panelId%3D1
Your computed URL is not “trusted” (with good reason, since it comes from an user-controlled template) so it is blocked.

A solution could be to have an item to hold your URL, with rules responding to commands and use HABPanel’s built-in “frame” widget which automatically sets URLs as trusted (which I now realize might not even be the best thing security-wise since items can easily be updated with the API).

Something like this:

<!-- You need to have server-side rules to update the Grafana_URL item
when the Grafana_Period item receives commands/updates -->
<div ng-init="model={ 'url_source': 'item', 'item': 'Grafana_URL' }"></div>
    <table>
    	<tr>
        <th> <button type="button" ng-click="sendCmd('Grafana_Period', '1h')">1h</button></th>
        <th> <button type="button" ng-click="sendCmd('Grafana_Period', '1d')">1d</button></th>
        <th> <button type="button" ng-click="sendCmd('Grafana_Period', '1w')">1w</button></th>
        <th> <button type="button" ng-click="sendCmd('Grafana_Period', '1m')">1m</button></th>
        <th> <button type="button" ng-click="sendCmd('Grafana_Period', '6m')">6m</button></th>
      </tr>
    </table>

<widget-frame ng-model="model"></widget-frame>
2 Likes

@ysc Hmm, can you think of any better way to allow time-period selection on grafana graphs. It’s quite an overhead to create an item, a rule and an iframe for each graph!

You could make an Angular controller for the widget which will trust the URLs with $sce.trustAsResourceUrl()

http://www.rubencanton.com/blog/2014/07/adding-video-src-with-angular.html

The filter option is the most elegant solution IMO.

angular.module('app')
  .filter('grafanaUrl', function ($sce) {
    return function(fromTime) {
      return $sce.trustAsResourceUrl('http://192.168.0.165:3000/dashboard...&from=' + fromTime + '&to=now&...');
    };
  });
<!-- lazy-load the filter in conf/html -->
<div oc-lazy-load="'/static/grafana.filter.js'">
  <iframe ng-src="{{from_time | grafana-url}}" ...></iframe>
</div>

Had a similar issue, the filter method a similar to the one as shown here works
at present as a general filter for all sce related issues.
Generating a grafana diagram by code, means i generate a link to grafana by
the subject of the diagram and time values additional to the static link, let fail the proposal as shown here.

The javascript got programmed as:

GrafanaFilter.js


      angular.module('filters-module', [])
      .filter('grafanaUrl', ['$sce', function($sce) {
          return function(url) {
              return $sce.trustAsResourceUrl(url);
          };
      }])

The diagram gets opened by the template code:

<div class="custom-diagramm" oc-lazy-load="'/static/GrafanaFilter.js'">     
  						<iframe 
                      ng-src="{{ itemValue('Diagram_URL')  | grafanaUrl}}" width="100%" height="100%" frameborder="0" > 
              </iframe>

 </div>

Diagram_URL is the complete link as string.

e.g. http://xxx.xxx.xxx.xx:yyyy/dashboard-solo/db/luft?orgId=1&panelId=1&kiosk&from=now-6h&to=now

The diagram gets opened as a modal window, see here the descriptions how to open a modal window.
Important is to address the oc-lazy-load in the outer div. It looks oc-lazy-load has an integrative div and as consequence the diagram didn’t achieve a height of 100 %.

Spoken easy…needed three weeks to get a understanding of the root cause as doing the same in a frame-widget worked pretty perfect from the beginning.
Ok, but now i have the luxury of a scaleable time range by a mouse click and a modal window to “zoom” diagrams if i like.