Splunk Search

Change the color of rows in a table based on text value in Splunk Enterprise v6.4

rijinc
Explorer

My Table is as follows

RAG status    Count
Red           1
Amber         4
Green         10
Grey          7

I am using this code from the link : https://answers.splunk.com/answers/230164/how-to-get-a-table-cell-color-to-change-depending.html

However I am not able to color the complete row, it jst colours the first column RAG status,can you let me know the issue where i am going wrong. Below is the JS and CSS file:
JS:

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

  // Row Coloring Example with custom, client-side range interpretation

 var CustomRangeRenderer = TableView.BaseCellRenderer.extend({
     canRender: function(cell) {
         // Enable this custom cell renderer for both the active_hist_searches and the active_realtime_searches field
          return _(['Overall Transition Status']).contains(cell.field);
     },
     render: function($td, cell) {

         var value = cell.value;

         if (cell.field === 'OTS') {
              if (value =='Green') {
                 $td.addClass('range-cell').addClass('range-green');
             }
             else if (value =='Amber') {
                 $td.addClass('range-cell').addClass('range-amber');
             }
             else if (value =='Grey-Not Submitted') {
                 $td.addClass('range-cell').addClass('range-grey');
             }
             else if (value =='Red') {
                 $td.addClass('range-cell').addClass('range-red');
             }

         }

         $td.text(value);
     }
 });

 mvc.Components.get('A1').getVisualization(function(tableView) {
     tableView.on('rendered', function() {
         tableView.$el.find('td.range-cell').each(function() {
             $(this).parents('tr').addClass(this.className);
         });
     });
     tableView.addCellRenderer(new CustomRangeRenderer());
 });

 });

CSS :

/* Row Coloring */
 #A1 tr.range-green td {
 background-color: #329606 !important;                  
 }

 #A1 tr.range-amber td {
 background-color: #F1FF70 !important;               
 }

 #A1 tr.range-red td {
 background-color: #D6344D !important;               
 }

 #A1 td.range-green, td.range-amber, td.range-red{
 font-weight: 800;
 }
1 Solution

niketn
Legend

@rijinc, I see issues with the you sample table, the JavaScript and CSS. I am not sure whether they actually exist or got introduced while posting you question with data and code sample.

Your table has field name as RAG status. However, your JavaScript refers to it as Overall Transition Status first and then OTS later in the JavaScript. Since you have returned only one column for deciding the custom range class based on its value, you do not need the second if with OTS anyways (that was required in Splunk Dashboard Examples since example applies color based on two rows).

Further you CSS does not have a range for Grey which you have provided in your sample as well as JavaScript. Finally font-weight: bold; was applied in the Splunk Dashboard Examples App to identify whether the Range class got successfully applied as per cell Value/s or not. So, if you have Green as your default row color. Ideally you should not apply bold font for Green range class.

Having said all this, assuming actual field name is RAG status to apply range class for row colors and your default row color is Green, following is a run anywhere dashboard with mock data as per the question:

alt text

Simple XML Code (table with id="highlight"):

<dashboard script="table_row_highlighting_by_category.js" stylesheet="table_decorations_by_category.css">
  <label>Color Row by Cell Value</label>
  <row>
    <panel>
      <table id="highlight">
        <search>
          <query>|  makeresults
|  eval data="Red,1;Amber,4;Green,10;Grey,7"
|  makemv data delim=";"
|  mvexpand data
|  eval data=split(data,",")
|  eval "RAG status"=mvindex(data,0)
|  eval Count=mvindex(data,1)
|  table "RAG status" Count</query>
          <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>

JavaScript Code (table_row_highlighting_by_category.js)

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

    var CustomRangeRenderer = TableView.BaseCellRenderer.extend({
        canRender: function(cell) {
            // Enable this custom cell renderer for RAG status field
            return _(["RAG status"]).contains(cell.field);
        },
        render: function($td, cell) {
            // Add a class to the cell based on the returned value
            var value = cell.value;

            // Apply interpretation for RAG status field
            // Since we have picked only one row for applying range Class, following if is not required.
            if (cell.field === "RAG status") {
                //Add range class based on cell values.
                if (value == "Green") {
                    $td.addClass("range-cell").addClass("range-green");
                }
                if (value == "Amber" ) {
                    $td.addClass("range-cell").addClass("range-amber");
                }
                if (value == "Red" ) {
                    $td.addClass("range-cell").addClass("range-red");
                }
                if (value == "Grey" ) {
                    $td.addClass("range-cell").addClass("range-grey");
                }               
            }

            // Update the cell content with string value
            $td.text(value).addClass('string');
        }
    });

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

        tableView.on('rendered', function() {
            // Add a delay to ensure Custom Render applies to row without getting overridden with built in reder.           
            setTimeout(function(){  
                // Apply class of the cells to the parent row in order to color the whole row
                tableView.$el.find('td.range-cell').each(function() {
                    $(this).parents('tr').addClass(this.className);
                });
            },100);
        });

        // Add custom cell renderer, the table will re-render automatically.
        tableView.addCellRenderer(new CustomRangeRenderer());
    });
});

CSS Code (table_decorations_by_category.css)

/* Row Coloring */

#highlight tr td {
    background-color: #65A637 !important;
}

#highlight tr.range-green td {
    background-color: #65A637 !important;
}

#highlight tr.range-amber td {
    background-color: #F7BC38 !important;
}
#highlight tr.range-red td {
    background-color: #D93F3C !important;
}

#highlight tr.range-grey td {
    background-color: #f3f3f3 !important;
}

#highlight .table td {
    border-top: 1px solid #fff;
}
/* 
Apply bold font for rows with custom range colors other than Green(default).
Bold font will ensure that jQuery is working fine to apply appropriate range Class. 
*/
#highlight td.range-amber, td.range-red, td.range-grey{
    font-weight: bold;
}

I recently noticed on 6.6+ that Row Colors applied based on range class was getting overridden by default color, even when the row color was being applied after rendering the table. Refer to one of my answers to add delay in JavaScript to apply Row colors on rendering the table to overcome this issue (not sure if you will get this issue in 6.4 but you can test without setTimeout() and with setTimeout() function): https://answers.splunk.com/answers/583047/can-i-color-a-cell-based-on-condition.html

Since the example requires JS and CSS static files ,you might need to refresh/ restart or bump Splunk for the changes to reflect. You might also need to clear your Web Browser history if changes do not reflect.

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

View solution in original post

niketn
Legend

@rijinc, I see issues with the you sample table, the JavaScript and CSS. I am not sure whether they actually exist or got introduced while posting you question with data and code sample.

Your table has field name as RAG status. However, your JavaScript refers to it as Overall Transition Status first and then OTS later in the JavaScript. Since you have returned only one column for deciding the custom range class based on its value, you do not need the second if with OTS anyways (that was required in Splunk Dashboard Examples since example applies color based on two rows).

Further you CSS does not have a range for Grey which you have provided in your sample as well as JavaScript. Finally font-weight: bold; was applied in the Splunk Dashboard Examples App to identify whether the Range class got successfully applied as per cell Value/s or not. So, if you have Green as your default row color. Ideally you should not apply bold font for Green range class.

Having said all this, assuming actual field name is RAG status to apply range class for row colors and your default row color is Green, following is a run anywhere dashboard with mock data as per the question:

alt text

Simple XML Code (table with id="highlight"):

<dashboard script="table_row_highlighting_by_category.js" stylesheet="table_decorations_by_category.css">
  <label>Color Row by Cell Value</label>
  <row>
    <panel>
      <table id="highlight">
        <search>
          <query>|  makeresults
|  eval data="Red,1;Amber,4;Green,10;Grey,7"
|  makemv data delim=";"
|  mvexpand data
|  eval data=split(data,",")
|  eval "RAG status"=mvindex(data,0)
|  eval Count=mvindex(data,1)
|  table "RAG status" Count</query>
          <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>

JavaScript Code (table_row_highlighting_by_category.js)

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

    var CustomRangeRenderer = TableView.BaseCellRenderer.extend({
        canRender: function(cell) {
            // Enable this custom cell renderer for RAG status field
            return _(["RAG status"]).contains(cell.field);
        },
        render: function($td, cell) {
            // Add a class to the cell based on the returned value
            var value = cell.value;

            // Apply interpretation for RAG status field
            // Since we have picked only one row for applying range Class, following if is not required.
            if (cell.field === "RAG status") {
                //Add range class based on cell values.
                if (value == "Green") {
                    $td.addClass("range-cell").addClass("range-green");
                }
                if (value == "Amber" ) {
                    $td.addClass("range-cell").addClass("range-amber");
                }
                if (value == "Red" ) {
                    $td.addClass("range-cell").addClass("range-red");
                }
                if (value == "Grey" ) {
                    $td.addClass("range-cell").addClass("range-grey");
                }               
            }

            // Update the cell content with string value
            $td.text(value).addClass('string');
        }
    });

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

        tableView.on('rendered', function() {
            // Add a delay to ensure Custom Render applies to row without getting overridden with built in reder.           
            setTimeout(function(){  
                // Apply class of the cells to the parent row in order to color the whole row
                tableView.$el.find('td.range-cell').each(function() {
                    $(this).parents('tr').addClass(this.className);
                });
            },100);
        });

        // Add custom cell renderer, the table will re-render automatically.
        tableView.addCellRenderer(new CustomRangeRenderer());
    });
});

CSS Code (table_decorations_by_category.css)

/* Row Coloring */

#highlight tr td {
    background-color: #65A637 !important;
}

#highlight tr.range-green td {
    background-color: #65A637 !important;
}

#highlight tr.range-amber td {
    background-color: #F7BC38 !important;
}
#highlight tr.range-red td {
    background-color: #D93F3C !important;
}

#highlight tr.range-grey td {
    background-color: #f3f3f3 !important;
}

#highlight .table td {
    border-top: 1px solid #fff;
}
/* 
Apply bold font for rows with custom range colors other than Green(default).
Bold font will ensure that jQuery is working fine to apply appropriate range Class. 
*/
#highlight td.range-amber, td.range-red, td.range-grey{
    font-weight: bold;
}

I recently noticed on 6.6+ that Row Colors applied based on range class was getting overridden by default color, even when the row color was being applied after rendering the table. Refer to one of my answers to add delay in JavaScript to apply Row colors on rendering the table to overcome this issue (not sure if you will get this issue in 6.4 but you can test without setTimeout() and with setTimeout() function): https://answers.splunk.com/answers/583047/can-i-color-a-cell-based-on-condition.html

Since the example requires JS and CSS static files ,you might need to refresh/ restart or bump Splunk for the changes to reflect. You might also need to clear your Web Browser history if changes do not reflect.

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

nileshgupta
Engager

How would I color only "Count" column based on the corresponding value in "RAG Status" Column in your example? i.e. if "RAG Status" have RED in a particular cell it corresponding(same row) cell in "Count" column only should color in Red.

I am looking for similar solution where I want to color cells based on the column name and the corresponding value in the first column of that row.

Many Thanks!

0 Karma

Cuyose
Builder

This no longer seems to work in Splunk 7.1, even duplicating this solution verbatim, all rows are colored the background color, meaning the evaluations are seemingly not evaluating to true anymore.

0 Karma

niketn
Legend

@Cuyose This works fine for me on Splunk 7.1.2. Have you performed a restart or refresh or bump of your Splunk instance after JavaScript change? Also, did you clear out Internet Browser History post static file changes?

alt text

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

Cuyose
Builder

Yes, thank you, it finally started working, however it was odd. Even after restart and cache flush repeatedly, it eventually started displaying correctly. The scripts all made sense, it was just getting the updates. Thanks a ton, good work, I wish this would come pre-packaged.

I did have a question though, I didn't have the time to dig into it, I know its possible, but how much work would it be to utilize the "built in" "auto range" cell coloring to apply to rows.

Basically doing the same thing, but not redefining the values to evaluate. Just have rows auto color based on like values of a specified field.

0 Karma

niketn
Legend

Are the number of columns in your table fixed? If so can you post a new question with some mock up data/screenshot of what your current table looks like and what is the output expected?

Meanwhile do Up Vote the answers/comments here on Splunk Answers that have helped you resolve your issue 🙂

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

Cuyose
Builder

Upvoted, thanks again. Yes they are fixed, Ill post new question and see what the community can come up with for me other question.

0 Karma

niketn
Legend

@Cuyose, Up vote is usually the Up Arrow Icon next to answers and shows up when you hover over a comment. ^. Waiting for your new question 🙂

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

Cuyose
Builder

For some reason I cannot make this work. The only thing applied is the css background color defined.

0 Karma

niketn
Legend

@nileshgupta sorry I missed this, refer to this answer by @kamlesh_vaghela...https://answers.splunk.com/answers/661894/how-to-color-cell-contents-with-css-and-js.html

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

rijinc
Explorer

@niketnilay

Thanks a lot... 🙂 vry much helpful

0 Karma

alacercogitatus
SplunkTrust
SplunkTrust

Why not do the td parent in the if/else statement above it?

if (cell.field === 'OTS') {
           if (value =='Green') {
              $td.addClass('range-cell').addClass('range-green');
              $td.parents('tr').find('td').addClass('range-green');
          }
          else if (value =='Amber') {
              $td.addClass('range-cell').addClass('range-amber');
              $td.parents('tr').find('td').addClass('range-amber');
          }
          else if (value =='Grey-Not Submitted') {
              $td.addClass('range-cell').addClass('range-grey');
              $td.parents('tr').find('td').addClass('range-grey');
          }
          else if (value =='Red') {
              $td.addClass('range-cell').addClass('range-red');
              $td.parents('tr').find('td').addClass('range-red');
          }

      }
0 Karma

rijinc
Explorer

$td.text(value);

--- > have something to do with this line in JS code . however not able to identify this in JS

0 Karma

rijinc
Explorer

any suggestion ?

0 Karma
Get Updates on the Splunk Community!

Introduction to Splunk Observability Cloud - Building a Resilient Hybrid Cloud

Introduction to Splunk Observability Cloud - Building a Resilient Hybrid Cloud  In today’s fast-paced digital ...

Observability protocols to know about

Observability protocols define the specifications or formats for collecting, encoding, transporting, and ...

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 ...