Splunk Search

Make table column header indicate the sort order of data in underlying search results?

I want the sort indicators (up/down arrowheads) in table visualization column headings to reflect the default sort order of the data supplied by the underlying search.

I'm using the sort command in Splunk 7.3.0 to sort the search results for a table by one of the fields in descending order. So the rows of the table are already sorted. However, the sort indicators in the visualization don't reflect that default sort order.

Instead of this:

Screenshot of table showing figures sorted in descending order, but sort indicators do not reflect that order

I want the table to show this, by default:

Screenshot of table showing figures sorted in descending order, reflected by a sort indicator

(How) can I do this? There doesn't appear to be a corresponding formatting option to set the table visualization sort indicators.

0 Karma
1 Solution

SplunkTrust
SplunkTrust

[UPDATED ANSWER]
Updated the answer to render the table only after search completes using <done> and added a token dependency to apply desc class to the icon for count so that it shows down arrow only when dashboard loads. After which it should respond to click on the table header.


@Graham_Hannington this would be possible through Simple XML JS Extension where on load of the table you can override the icon of table header using SplunkJS.

In the following run anywhere example I have a table with id="my_table_with_default_sort" which I am accessing via JS to override icon class as desc to apply icon.

<dashboard script="table_default_sort.js">
  <label>Table with Sort</label>
  <init>
    <set token="tokTableOnLoad">true</set>
  </init>
  <row>
    <panel>
      <table id="my_table_with_default_sort" depends="$tokRenderTableOnSearchCompletion$">
        <search>
          <query>index=_internal sourcetype=splunkd log_level!=INFO
| stats count by component
| sort 0 -count</query>
          <done>
            <set token="tokRenderTableOnSearchCompletion">true</set>
          </done>
          <earliest>-24h@h</earliest>
          <latest>now</latest>
          <sampleRatio>1</sampleRatio>
        </search>
        <option name="count">20</option>
        <option name="dataOverlayMode">none</option>
        <option name="drilldown">none</option>
        <option name="percentagesRow">false</option>
        <option name="rowNumbers">false</option>
        <option name="totalsRow">false</option>
        <option name="wrap">true</option>
      </table>
    </panel>
  </row>
</dashboard>

Following is the required JS table_default_sort.js

require(["jquery",
         "splunkjs/mvc",
         "splunkjs/mvc/tableview",
         "splunkjs/mvc/simplexml/ready!"],
 function ($,
          mvc,
          TableView) {
    var defaultTokenModel=mvc.Components.get("default");

    mvc.Components.get('my_table_with_default_sort').getVisualization(function (tableView) {
        tableView.on('rendered', function () {
            setTimeout(function(){
                var strTokTableOnLoad=defaultTokenModel.get("tokTableOnLoad");
                // Get the Token tokTableOnLoad which is set in the <init> section for the first time override of table sort icon for count column
                if(strTokTableOnLoad!==undefined){
                $('#my_table_with_default_sort table th[data-sort-key="count"] a i').addClass("desc");
                    // Unset the token tokTableOnLoad so that Table icon override never happens for the second time.
                    defaultTokenModel.unset("tokTableOnLoad");
                }
            },100);
        });
    });
});

Please try out and confirm!

____________________________________________
| makeresults | eval message= "Happy Splunking!!!"

View solution in original post

0 Karma

I am surprised that this behavior is not already baked in to Splunk, at 7.3.x. Having tables reflect the default sort order of their data seems such an obvious thing to do. Is my use case so atypical? I understand that this might be a low priority, but still, isn't it "low-hanging fruit": relatively easy for the Splunk developers to add options to the table viz to support this behavior (say, sortColumn, sortOrder)?

0 Karma

SplunkTrust
SplunkTrust

[UPDATED ANSWER]
Updated the answer to render the table only after search completes using <done> and added a token dependency to apply desc class to the icon for count so that it shows down arrow only when dashboard loads. After which it should respond to click on the table header.


@Graham_Hannington this would be possible through Simple XML JS Extension where on load of the table you can override the icon of table header using SplunkJS.

In the following run anywhere example I have a table with id="my_table_with_default_sort" which I am accessing via JS to override icon class as desc to apply icon.

<dashboard script="table_default_sort.js">
  <label>Table with Sort</label>
  <init>
    <set token="tokTableOnLoad">true</set>
  </init>
  <row>
    <panel>
      <table id="my_table_with_default_sort" depends="$tokRenderTableOnSearchCompletion$">
        <search>
          <query>index=_internal sourcetype=splunkd log_level!=INFO
| stats count by component
| sort 0 -count</query>
          <done>
            <set token="tokRenderTableOnSearchCompletion">true</set>
          </done>
          <earliest>-24h@h</earliest>
          <latest>now</latest>
          <sampleRatio>1</sampleRatio>
        </search>
        <option name="count">20</option>
        <option name="dataOverlayMode">none</option>
        <option name="drilldown">none</option>
        <option name="percentagesRow">false</option>
        <option name="rowNumbers">false</option>
        <option name="totalsRow">false</option>
        <option name="wrap">true</option>
      </table>
    </panel>
  </row>
</dashboard>

Following is the required JS table_default_sort.js

require(["jquery",
         "splunkjs/mvc",
         "splunkjs/mvc/tableview",
         "splunkjs/mvc/simplexml/ready!"],
 function ($,
          mvc,
          TableView) {
    var defaultTokenModel=mvc.Components.get("default");

    mvc.Components.get('my_table_with_default_sort').getVisualization(function (tableView) {
        tableView.on('rendered', function () {
            setTimeout(function(){
                var strTokTableOnLoad=defaultTokenModel.get("tokTableOnLoad");
                // Get the Token tokTableOnLoad which is set in the <init> section for the first time override of table sort icon for count column
                if(strTokTableOnLoad!==undefined){
                $('#my_table_with_default_sort table th[data-sort-key="count"] a i').addClass("desc");
                    // Unset the token tokTableOnLoad so that Table icon override never happens for the second time.
                    defaultTokenModel.unset("tokTableOnLoad");
                }
            },100);
        });
    });
});

Please try out and confirm!

____________________________________________
| makeresults | eval message= "Happy Splunking!!!"

View solution in original post

0 Karma

I've accepted this answer because it works for the question I asked. @niketnilay deserves credit for that.

However, there's a caveat: I can't—or rather, won't—be using this answer in practice, because, in my opinion, it's too onerous to implement. The code presented in this answer is specific to a particular table visualization. I'm considering asking a new, follow-on, more carefully worded question to address this.

SplunkTrust
SplunkTrust

@Graham_Hannington thanks for accepting the answer. And trust me I have got your followup question for making this generic for all tableViews in the dashboard. Which is doable, but I would be able to spend time for creating an example only o we the weekend. So hang tight (hopefully I get to spend time as I have pipelinedquite many such challenges for the weekend).

____________________________________________
| makeresults | eval message= "Happy Splunking!!!"
0 Karma

Hi @niketnilay,

With apologies for the belated reply (I was on leave for a couple of days): thanks very much! Yes, that worked!

Nit: to get your code to work, I had to change tokRenderTableOnSearchCompletion in the dashboard source to match the corresponding token name tokTableOnLoad in the JavaScript. At least—I write this in case I'm completely misunderstanding something here—it didn't work at first, and then I made that change, and then it worked.

So... I suppose I should accept your answer immediately. And, if that's what you'd prefer, after reading the rest of this comment, I'll do just that.

Your current answer works for a specific table: with hardcoded table ID, sorted column name, and sort order.

I want to apply this behavior to multiple tables on a dashboard. I don't want to create a separate .js file for each table. I can't bring myself to implement this answer in code that I'm going to deliver to customers. (My problem? Sure.)

I've started experimenting with JavaScript that will iterate over all table views in a dashboard:

$.each(mvc.Components.getInstances(), function (i, view) {
  if (view instanceof TableView) {
    view.on('rendered', function(view) {setDefaultSort(view)});
  }
});

but tokens are—unless I'm mistaken; I might be—by definition dashboard-wide, not view-specific, so this token-based approach does not work for multiple views in a dashboard.

I've started to look into other ways to pass a sort column name and sort order through to the JavaScript, and to have the rendering occur only on page load, but I feel like I'm heading down a developmental rabbit hole (custom visualization?) that I don't have time to explore.

Your thoughts?

0 Karma

Extending the table cell renderer initially occurred to me as a possibility, but it seems that the cell renderer is limited to the table body cells (td); I can't find a way to extend the rendering of the table header cells (th).

0 Karma