Splunk Search

Javascript tooltip showing results of a CSV lookup

alai
Explorer

Hi all,

we do have a table showing (besides other information) HTTP status codes. I'm trying to implement a tooltip that shows the corresponding status code description when hovering over with the mouse. The descriptions are in a CSV file which comes with the CIM.

I found a useful blog (Add a Tooltip to Simple XML Tables..) describing how a tooltip can be implemented. I tried to modify it by including a search / lookup but can't get it to work as expected:

require([
    'underscore',
    'jquery',
    'splunkjs/mvc',
    'splunkjs/mvc/tableview',
    'splunkjs/mvc/searchmanager',
    'splunkjs/mvc/simplexml/ready!'
], function(_, $, mvc, TableView, SearchManager) {

        canRender: function(cell) {
            return cell.field === 'Status';
        },
        render: function($td, cell) {

            var mySearch = new SearchManager({
                "id": "my_search_id",
                "search": '| lookup cim_http_status_lookup status as "' + cell.value + '" OUTPUT status_description as stat_desc | table stat_desc'
            }, { tokens: true });

            var stat = cell.value;
            var stat_desc = mySearch.data("results");

            $td.html(_.template('<a href="#" data-toggle="tooltip" data-container="body" data-placement="top" title="<%- stat_desc%>"><%- stat%></a>', {
                stat_desc: stat_desc,
                stat: stat
            }));

            // This line wires up the Bootstrap tooltip to the cell markup
            $td.children('[data-toggle="tooltip"]').tooltip();
        }
    });

    mvc.Components.get('nginx_access_expand_table').getVisualization(function(tableView) {

        // Register custom cell renderer
        tableView.table.addCellRenderer(new CustomTooltipRenderer());

        // Force the table to re-render
        tableView.table.render();
    });

});

Thanks for your feedback.

0 Karma
1 Solution

kamlesh_vaghela
SplunkTrust
SplunkTrust

Hello @alai,

In below blog only main steps are mentioned which are important to implement tooltip feature in Table. I believe you have implemented full code for your dashboard.

https://www.splunk.com/blog/2014/01/29/add-a-tooltip-to-simple-xml-tables-with-bootstrap-and-a-custo...

Well, it seems you want to display value from the lookup table to display the status description in a tooltip for respective status. And you are executing a search to get a status description from the lookup.

Here I suggest you to incorporate lookup search in your table search and not need to execute search individually status wise.

Check https://docs.splunk.com/Documentation/Splunk/7.2.4/SearchReference/Lookup link you will find the lookup examples.

With the single search, you can see my answer in the below post. You can achive the same thing without execute any other search.

https://answers.splunk.com/answers/592103/how-can-i-show-multiple-values-on-a-tooltip-from-a.html

But I'm sharing a solution, what if we want to execute search incase Single search is not possible with Table. I'm taking your problem statement as an example.

In your code, you have used SearchManager to execute a search. But here I have used service to execute search and process results.

Check http://dev.splunk.com/view/javascript-sdk/SP-CAAAEFA for more information about service.search.

Below is the full implementation: You have to just copy-paste it to try. I have used sample searches. You can change it as per your need.

test.xml

<dashboard script="test.js" stylesheet="test.css">
  <label>Tooltip on Table</label>
  <row>
    <panel>
      <table id="tableTest">
        <title>My Table</title>
        <search>
          <query>| makeresults count=5 | eval num=1 | accum num |  eval Status="Hello Status "+num | table _time Status</query>
          <earliest>-15m</earliest>
          <latest>now</latest>
        </search>
        <option name="count">10</option>
        <option name="drilldown">none</option>
        <option name="refresh.display">progressbar</option>
      </table>
    </panel>
  </row>
</dashboard>

test.js

 require([
    'underscore',
    'jquery',
    'splunkjs/mvc',
    'splunkjs/mvc/tableview',
    'splunkjs/mvc/searchmanager',
    'splunkjs/mvc/simplexml/ready!'
], function(_, $, mvc, TableView,SearchManager) {
    var CustomRangeRenderer = TableView.BaseCellRenderer.extend({
        canRender: function(cell) {
             return cell.field === 'Status';
        },
        render: function($td, cell) {
            var cell_value = cell.value;
            var searchQuery = '| makeresults | eval StatusTooltip="Hello from '+cell_value+' " | table StatusTooltip'
            var searchParams = {
                exec_mode: "blocking",
                earliest_time: "2012-06-20T16:27:43.000-07:00"
            };
            var service = mvc.createService();
            console.log("Wait for the search to finish...");

            service.search(
                searchQuery,
                searchParams,
                function(err, job) {
                    console.log("...done!\n");

                    // Get the job from the server to display more info
                    job.fetch(function(err){
                        // Get the results and display them
                        job.results({}, function(err, results) {
                            var fields = results.fields;
                            var rows = results.rows;
                            var ret_value=results.rows[0][0];
                            console.log(cell_value,ret_value);
                            console.log(fields);
                            console.log(rows);
                            $td.html(_.template('<a href="#" data-toggle="tooltip" data-container="body" data-placement="top" title="<%- stat_desc%>"><%- stat%></a>', {
                                stat_desc: ret_value,
                                stat: cell_value
                            }));
                            $td.children('[data-toggle="tooltip"]').tooltip();
                        })
                    });
                }
            );             
        }
    });

    //List of table IDs to add icon
    var tableIDs = ["tableTest"];
    for (i=0;i<tableIDs.length;i++) {
        var sh = mvc.Components.get(tableIDs[i]);
        if(typeof(sh)!="undefined") {
            sh.getVisualization(function(tableView) {
                // Add custom cell renderer and force re-render
                tableView.table.addCellRenderer(new CustomRangeRenderer());
                tableView.table.render();
            });
        }
    }    
});

test.css

.tooltip-inner { max-width: 400px;
text-align: left;
font-size: 14px;
font-weight: normal;
}

Thanks

View solution in original post

ss026381
Communicator

Hey @kamlesh_vaghela, I tried your code and it works fine, but do you know why "top,auto" for data-placement doesn't work properly. I see it works fine outside the Splunk but when I use the JS with dashboard it doesn't work.
The working example outside the Splunk dashboard: https://www.w3schools.com/bootstrap/bootstrap_tooltip.asp

0 Karma

kamlesh_vaghela
SplunkTrust
SplunkTrust

@ss026381

Apology for the late reply. Can you please share your code?? Please mask your original values with dummy.

Thanks

0 Karma

ss026381
Communicator

This is the js file, I am enabling tooltip on columns starts with list of and for all tables that ends with with_tooltip

require([
    'underscore',
    'jquery',
    'splunkjs/mvc',
    'splunkjs/mvc/tableview',
    'splunkjs/mvc/simplexml/ready!'
], function(_, $, mvc, TableView) {

    var CustomTooltipRenderer = TableView.BaseCellRenderer.extend({
        canRender: function(cell) {
            var re = /list\s*of.*/i;
            var result = cell.field.match(re);
            if(result){
                return cell.field;
            }
            return
        },
        render: function($td, cell) {

            var message = cell.value;
            var tip = cell.value;
            if(message.length > 15) { message = message.substring(0,14) + "..."
            $td.html(_.template('<a href="#" data-toggle="tooltip" data-placement="left auto" title="<%- tip%>"><%- message%></a>', {
                tip: tip,
                message: message
            }));

            $td.children('[data-toggle="tooltip"]').tooltip();
            }
            else{
                $td.html(_.template(message, {
                tip: tip,
                message: message
            }));
            }
        }
    });

    var tableIDs = [];
    var domeElements = document.getElementsByTagName("div");
    for(var i=0;i<domeElements.length;i++)
    {
        if(domeElements[i].id != "undefined" && domeElements[i].id.match(/.*with_tooltip$/i)){
            tableIDs.push(domeElements[i].id);
        }
    }
    for(i = 0; i < tableIDs.length; i++){
        mvc.Components.get(tableIDs[i]).getVisualization(function(tableView) {
            tableView.table.addCellRenderer(new CustomTooltipRenderer());
            tableView.table.render();
        });
    }
});

It shows something like this, My guess is it's missing some of bootstrap libraries or I am doing something wrong.

alt text

0 Karma

kamlesh_vaghela
SplunkTrust
SplunkTrust

Hello @alai,

In below blog only main steps are mentioned which are important to implement tooltip feature in Table. I believe you have implemented full code for your dashboard.

https://www.splunk.com/blog/2014/01/29/add-a-tooltip-to-simple-xml-tables-with-bootstrap-and-a-custo...

Well, it seems you want to display value from the lookup table to display the status description in a tooltip for respective status. And you are executing a search to get a status description from the lookup.

Here I suggest you to incorporate lookup search in your table search and not need to execute search individually status wise.

Check https://docs.splunk.com/Documentation/Splunk/7.2.4/SearchReference/Lookup link you will find the lookup examples.

With the single search, you can see my answer in the below post. You can achive the same thing without execute any other search.

https://answers.splunk.com/answers/592103/how-can-i-show-multiple-values-on-a-tooltip-from-a.html

But I'm sharing a solution, what if we want to execute search incase Single search is not possible with Table. I'm taking your problem statement as an example.

In your code, you have used SearchManager to execute a search. But here I have used service to execute search and process results.

Check http://dev.splunk.com/view/javascript-sdk/SP-CAAAEFA for more information about service.search.

Below is the full implementation: You have to just copy-paste it to try. I have used sample searches. You can change it as per your need.

test.xml

<dashboard script="test.js" stylesheet="test.css">
  <label>Tooltip on Table</label>
  <row>
    <panel>
      <table id="tableTest">
        <title>My Table</title>
        <search>
          <query>| makeresults count=5 | eval num=1 | accum num |  eval Status="Hello Status "+num | table _time Status</query>
          <earliest>-15m</earliest>
          <latest>now</latest>
        </search>
        <option name="count">10</option>
        <option name="drilldown">none</option>
        <option name="refresh.display">progressbar</option>
      </table>
    </panel>
  </row>
</dashboard>

test.js

 require([
    'underscore',
    'jquery',
    'splunkjs/mvc',
    'splunkjs/mvc/tableview',
    'splunkjs/mvc/searchmanager',
    'splunkjs/mvc/simplexml/ready!'
], function(_, $, mvc, TableView,SearchManager) {
    var CustomRangeRenderer = TableView.BaseCellRenderer.extend({
        canRender: function(cell) {
             return cell.field === 'Status';
        },
        render: function($td, cell) {
            var cell_value = cell.value;
            var searchQuery = '| makeresults | eval StatusTooltip="Hello from '+cell_value+' " | table StatusTooltip'
            var searchParams = {
                exec_mode: "blocking",
                earliest_time: "2012-06-20T16:27:43.000-07:00"
            };
            var service = mvc.createService();
            console.log("Wait for the search to finish...");

            service.search(
                searchQuery,
                searchParams,
                function(err, job) {
                    console.log("...done!\n");

                    // Get the job from the server to display more info
                    job.fetch(function(err){
                        // Get the results and display them
                        job.results({}, function(err, results) {
                            var fields = results.fields;
                            var rows = results.rows;
                            var ret_value=results.rows[0][0];
                            console.log(cell_value,ret_value);
                            console.log(fields);
                            console.log(rows);
                            $td.html(_.template('<a href="#" data-toggle="tooltip" data-container="body" data-placement="top" title="<%- stat_desc%>"><%- stat%></a>', {
                                stat_desc: ret_value,
                                stat: cell_value
                            }));
                            $td.children('[data-toggle="tooltip"]').tooltip();
                        })
                    });
                }
            );             
        }
    });

    //List of table IDs to add icon
    var tableIDs = ["tableTest"];
    for (i=0;i<tableIDs.length;i++) {
        var sh = mvc.Components.get(tableIDs[i]);
        if(typeof(sh)!="undefined") {
            sh.getVisualization(function(tableView) {
                // Add custom cell renderer and force re-render
                tableView.table.addCellRenderer(new CustomRangeRenderer());
                tableView.table.render();
            });
        }
    }    
});

test.css

.tooltip-inner { max-width: 400px;
text-align: left;
font-size: 14px;
font-weight: normal;
}

Thanks

alai
Explorer

Brilliant @kamlesh_vaghela that did the trick.

For reference here's my search query:

var searchQuery = '| makeresults | eval status ="'+cell.value+'" | lookup cim_http_status_lookup status as status OUTPUT status_description as stat_desc | table stat_desc'

Thank you very much!

0 Karma

kamlesh_vaghela
SplunkTrust
SplunkTrust

@alai
Glad to help you.

Happy Splunking

0 Karma

divvyamehta
New Member

Tooltip requires css library like bootstrap, have you imported them ?

0 Karma
Get Updates on the Splunk Community!

What's New in Splunk Enterprise 9.4: Features to Power Your Digital Resilience

Hey Splunky People! We are excited to share the latest updates in Splunk Enterprise 9.4. In this release we ...

Take Your Breath Away with Splunk Risk-Based Alerting (RBA)

WATCH NOW!The Splunk Guide to Risk-Based Alerting is here to empower your SOC like never before. Join Haylee ...

SignalFlow: What? Why? How?

What is SignalFlow? Splunk Observability Cloud’s analytics engine, SignalFlow, opens up a world of in-depth ...