hi guys,
I have been trying to color a table in a Splunk dashboard, but I need the color ranges to be different for each row:
Example:
Context Field 1 Field 2 Field 3
A 8 -4 9
B 8 -4 9
C 8 -4 9
For row where column Context is A: color green when the value is > 5 , red if the value < -5
For row where column Context is B: color blue when the value is > 5, yellow if the value < -5
For row where column Context is C: color orange when the value is > 5, pink if the value < -5
So, I tested with Javascript something that for a normal HTML page works. However, for the Splunk results table, it does not work.
what am I missing??
In Splunk, I built my SimpleXML table, then converted to HTML and inserted my Javascript code.
For an HTML page, this sample I built works:
<head>
<title>Sample code </title>
<script>
function start() {
var body = document.getElementsByTagName("body")[0];
var table = body.getElementsByClassName("table")[0];
var tbody = table.getElementsByTagName('tbody')[0];
for (var j=0; j<3; j++){
var rows = tbody.getElementsByTagName('tr')[j];
var cells = rows.getElementsByTagName('td');
for (var i=0, len=cells.length; i<len; i++){
if (cells[0].innerHTML == "A"){
if (parseInt(cells[i].innerHTML,10) > 5){
cells[i].style.backgroundColor = 'green';
}
else if (parseInt(cells[i].innerHTML,10) < -5){
cells[i].style.backgroundColor = 'red';
}
}
if (cells[0].innerHTML == "B"){
if (parseInt(cells[i].innerHTML,10) > 5){
cells[i].style.backgroundColor = 'blue';
}
else if (parseInt(cells[i].innerHTML,10) < -5){
cells[i].style.backgroundColor = 'yellow';
}
}
if (cells[0].innerHTML == "C"){
if (parseInt(cells[i].innerHTML,10) > 5){
cells[i].style.backgroundColor = 'orange';
}
else if (parseInt(cells[i].innerHTML,10) < -5){
cells[i].style.backgroundColor = 'pink';
}
}
}
}
}
</script>
</head>
<body onload="start()">
</br></br></br></br></br>
<table id="tableID" class="table" border="2" style="padding: 0.2em 0.5em" align="center">
<thead>
<tr>
<th>Context</th>
<th>Field 1</th>
<th>Field 2</th>
<th>Field 3</th>
</tr>
</thead>
<tbody>
<tr>
<td style="font-size: 50pt">A</td>
<td style="font-size: 50pt">8</td>
<td style="font-size: 50pt">-4</td>
<td style="font-size: 50pt">-9</td>
</tr>
<tr>
<td style="font-size: 50pt">B</td>
<td style="font-size: 50pt">8</td>
<td style="font-size: 50pt">-4</td>
<td style="font-size: 50pt">-9</td>
</tr>
<tr>
<td style="font-size: 50pt">C</td>
<td style="font-size: 50pt">8</td>
<td style="font-size: 50pt">-4</td>
<td style="font-size: 50pt">-9</td>
</tr>
</tbody>
</table>
</body>
</html>
@asimagu based on the answer by our Trust Fez bearer @kamlesh_vaghela please find below an answer specific to your query.
Step 1) Prefix all Field values with the Context value with pipe and delimeter character (or any other delimeter of your choice except hyphen which is same as minus sign as per your data.). First table displays the same result (it does not apply range color by context as it is only for example of data for customer table cell rendering.)
Step 2) Give your table a specific id in Simple XML i.e. id="tableWithColorBasedOnContext"
, in the run anywhere search attached. PS: The first table in the example does not have table id so range color by context does not apply.
Step 3) Add Customer table Cell renderer and pull three required Field cells i.e. Field1
, Field2
and Field3
in the above example. Apply custom JS section to split Context and Value for each field using delimeter (i.e. pipe |
in the example).
Step 4) Add custom CSS Style class based on the context and range i.e. range-green
, range-red
etc.
Step 5) Create CSS Style section to apply CSS Style override for table with specific background color class. For example:
#tableWithColorBasedOnContext .range-green{
background:green;
}
Please try out the following Run anywhere example and confirm:
1) Run anywhere Simple XML Dashboard Code
<dashboard script="table_row_color_by_context_and_range.js">
<label>Table Color by Context</label>
<row>
<panel>
<title>Table without Color Based on Context</title>
<table>
<search>
<query>| makeresults
| eval data="A,8,-6,0;B,6,-2,-9;C,0,7,-8"
| makemv data delim=";"
| mvexpand data
| makemv data delim=","
| eval Context=mvindex(data,0),Field1=mvindex(data,1),Field2=mvindex(data,2),Field3=mvindex(data,3)
| table Context Field*
| foreach Field1, Field2, Field3 [| eval <<FIELD>>=Context."|".<<FIELD>>]</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>
<row>
<panel>
<title>Table with Color Based on Context</title>
<table id="tableWithColorBasedOnContext">
<search>
<query>| makeresults
| eval data="A,8,-6,0;B,6,-2,-9;C,0,7,-8"
| makemv data delim=";"
| mvexpand data
| makemv data delim=","
| eval Context=mvindex(data,0),Field1=mvindex(data,1),Field2=mvindex(data,2),Field3=mvindex(data,3)
| table Context Field*
| foreach Field1, Field2, Field3 [| eval <<FIELD>>=Context."|".<<FIELD>>]</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>
<html depends="$alwaysHideStyleCSS$">
<style>
#tableWithColorBasedOnContext .range-green{
background:green;
}
#tableWithColorBasedOnContext .range-red{
background:red;
}
#tableWithColorBasedOnContext .range-blue{
background:lightblue;
}
#tableWithColorBasedOnContext .range-yellow{
background:yellow;
}
#tableWithColorBasedOnContext .range-orange{
background:orange;
}
#tableWithColorBasedOnContext .range-pink{
background:pink;
}
</style>
</html>
</panel>
</row>
</dashboard>
2) JavaScript file table_row_color_by_context_and_range.js
To be put under your Splunk app's appserver/static
folder. (PS: You may need bump, refresh, restart of your Splunk instance depending on the need. Also, you may be required to clean your Internet Browser's history for Static file changes to reflect properly.)
require([
'underscore',
'jquery',
'splunkjs/mvc',
'splunkjs/mvc/tableview',
'splunkjs/mvc/simplexml/ready!'
], function (_, $, mvc, TableView) {
console.log("Script Started");
var CustomRangeRenderer = TableView.BaseCellRenderer.extend({
canRender: function (cell) {
console.log("Starting Custom Renderer");
return _(['Field1', 'Field2', 'Field3']).contains(cell.field);
},
render: function ($td, cell) {
var context = cell.value.split("|")[0];
var value = parseInt(cell.value.split("|")[1]);
if (context == "A") {
if (value > 5) {
$td.addClass('range-green');
} else if (value < -5) {
$td.addClass('range-red');
}
}
if (context == "B") {
if (value > 5) {
$td.addClass('range-blue');
} else if (value < -5) {
$td.addClass('range-yellow');
}
}
if (context == "C") {
if (value > 5) {
$td.addClass('range-orange');
} else if (value < -5) {
$td.addClass('range-pink');
}
}
$td.text(value).addClass('numeric');
}
});
mvc.Components.get('tableWithColorBasedOnContext').getVisualization(function (tableView) {
tableView.addCellRenderer(new CustomRangeRenderer());
});
});
I need help coloring rows FONT text based on a cell value
Logic is like below
case(match(value,"logLevel=INFO"),"#4f34eb",match(value,"logLevel=WARNING"),"#ffff00",match(value,"logLevel=ERROR"),"#53A051",true(),"#ffffff")
@asimagu based on the answer by our Trust Fez bearer @kamlesh_vaghela please find below an answer specific to your query.
Step 1) Prefix all Field values with the Context value with pipe and delimeter character (or any other delimeter of your choice except hyphen which is same as minus sign as per your data.). First table displays the same result (it does not apply range color by context as it is only for example of data for customer table cell rendering.)
Step 2) Give your table a specific id in Simple XML i.e. id="tableWithColorBasedOnContext"
, in the run anywhere search attached. PS: The first table in the example does not have table id so range color by context does not apply.
Step 3) Add Customer table Cell renderer and pull three required Field cells i.e. Field1
, Field2
and Field3
in the above example. Apply custom JS section to split Context and Value for each field using delimeter (i.e. pipe |
in the example).
Step 4) Add custom CSS Style class based on the context and range i.e. range-green
, range-red
etc.
Step 5) Create CSS Style section to apply CSS Style override for table with specific background color class. For example:
#tableWithColorBasedOnContext .range-green{
background:green;
}
Please try out the following Run anywhere example and confirm:
1) Run anywhere Simple XML Dashboard Code
<dashboard script="table_row_color_by_context_and_range.js">
<label>Table Color by Context</label>
<row>
<panel>
<title>Table without Color Based on Context</title>
<table>
<search>
<query>| makeresults
| eval data="A,8,-6,0;B,6,-2,-9;C,0,7,-8"
| makemv data delim=";"
| mvexpand data
| makemv data delim=","
| eval Context=mvindex(data,0),Field1=mvindex(data,1),Field2=mvindex(data,2),Field3=mvindex(data,3)
| table Context Field*
| foreach Field1, Field2, Field3 [| eval <<FIELD>>=Context."|".<<FIELD>>]</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>
<row>
<panel>
<title>Table with Color Based on Context</title>
<table id="tableWithColorBasedOnContext">
<search>
<query>| makeresults
| eval data="A,8,-6,0;B,6,-2,-9;C,0,7,-8"
| makemv data delim=";"
| mvexpand data
| makemv data delim=","
| eval Context=mvindex(data,0),Field1=mvindex(data,1),Field2=mvindex(data,2),Field3=mvindex(data,3)
| table Context Field*
| foreach Field1, Field2, Field3 [| eval <<FIELD>>=Context."|".<<FIELD>>]</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>
<html depends="$alwaysHideStyleCSS$">
<style>
#tableWithColorBasedOnContext .range-green{
background:green;
}
#tableWithColorBasedOnContext .range-red{
background:red;
}
#tableWithColorBasedOnContext .range-blue{
background:lightblue;
}
#tableWithColorBasedOnContext .range-yellow{
background:yellow;
}
#tableWithColorBasedOnContext .range-orange{
background:orange;
}
#tableWithColorBasedOnContext .range-pink{
background:pink;
}
</style>
</html>
</panel>
</row>
</dashboard>
2) JavaScript file table_row_color_by_context_and_range.js
To be put under your Splunk app's appserver/static
folder. (PS: You may need bump, refresh, restart of your Splunk instance depending on the need. Also, you may be required to clean your Internet Browser's history for Static file changes to reflect properly.)
require([
'underscore',
'jquery',
'splunkjs/mvc',
'splunkjs/mvc/tableview',
'splunkjs/mvc/simplexml/ready!'
], function (_, $, mvc, TableView) {
console.log("Script Started");
var CustomRangeRenderer = TableView.BaseCellRenderer.extend({
canRender: function (cell) {
console.log("Starting Custom Renderer");
return _(['Field1', 'Field2', 'Field3']).contains(cell.field);
},
render: function ($td, cell) {
var context = cell.value.split("|")[0];
var value = parseInt(cell.value.split("|")[1]);
if (context == "A") {
if (value > 5) {
$td.addClass('range-green');
} else if (value < -5) {
$td.addClass('range-red');
}
}
if (context == "B") {
if (value > 5) {
$td.addClass('range-blue');
} else if (value < -5) {
$td.addClass('range-yellow');
}
}
if (context == "C") {
if (value > 5) {
$td.addClass('range-orange');
} else if (value < -5) {
$td.addClass('range-pink');
}
}
$td.text(value).addClass('numeric');
}
});
mvc.Components.get('tableWithColorBasedOnContext').getVisualization(function (tableView) {
tableView.addCellRenderer(new CustomRangeRenderer());
});
});
it works like a charm! thanks so much @niketnilay
@niketnilay is there any way of getting all the fields without hardcoding the names in the javascript?? something like return _(['*']).contains(cell.field); for line 12 in the script
@asimagu refer to one of my older answers: https://answers.splunk.com/answers/618930/how-can-i-get-the-table-cell-colorization-renderin-1.html
It uses SearchManager
from SplunkJS stack to get the list of fields returned and filters out unwanted fields (in the example it was _time but in your case it will be Context).
Alternatively, you can use an independent search in your dashboard to get all the field names and assign the list of comma separated field names as token which you can access in Splunk JS using Token Manger.
Please try out and confirm if you need assistance with any of the approach.
thanks a lot @niketnilay !! I got it working!
@asimagu,
There is a simpler way you can do it. I suggest you form your table first using a normal search text box (not in the dashboard). Then use the individual cell formatting option to color the column cells based on its value. In the screenshot, I used ranges to decide the color.
Then, if you are satisfied with the colors of all your cells, simply save it as a 'dashboard panel'.
Of course there are other ways to achieve this using CSS and javascript, but if this gets our job done, then I would say let's avoid those many lines of code.
Let me know if this helps.
@pramit46 each row should have a different condition for the colours. the default splunk does not provide this