Dashboards & Visualizations

Icon in a dashboard

Mathilde
Explorer

Hi all !

I want to display icon (alert-circle, alert, check-circle) instead of "OK", "POK" or "NOK" in a dashboard for 3 tables.

I have a js script for that.
It does the job only for table1 and table2. But, it doesn't work for table3.
It's the same code and every id is unique.

Code :
****mvc.Components.get('table1').getVisualization(function(tableView){
tableView.table.addCellRenderer(new RangeMapIconRenderer());
tableView.table.render();
}
****

If you have an idea or an explanation 🙂

Thanks !

Tags (1)

Mathilde
Explorer

Thanks for your answer !
I checked all the code but there's still the issue.
Maybe another look will help !

Simple XML (I put *** for the Splunk queries because of confidential purposes)

<dashboard script="cell_fill_gauge.js, table_icons_rangemap.js" stylesheet="table_decorations.css">
  <label>Surveillance</label>
  <row>
    <panel>
      <title>Disk Usage</title>
      <table id="disk_usage">
        <search>
          <query>***</query>
          <sampleRatio>1</sampleRatio>
        </search>
        <option name="count">10</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>
        <format type="number" field="Disk Usage (GB)"></format>
      </table>
    </panel>
  </row>
  <row>
    <panel>
      <title>Indexes</title>
      <table id="indexes">
        <search>
          <query>***</query>
          <earliest>$earliest$</earliest>
          <latest>$latest$</latest>
          <sampleRatio>1</sampleRatio>
        </search>
        <option name="count">20</option>
        <option name="dataOverlayMode">none</option>
        <option name="drilldown">cell</option>
        <option name="percentagesRow">false</option>
        <option name="rowNumbers">true</option>
        <option name="totalsRow">false</option>
        <option name="wrap">true</option>
      </table>
    </panel>
  </row>
  <row>
    <panel>
      <title>Etat des sondes</title>
      <table>
        <search>
          <query>***</query>
          <earliest>0</earliest>
          <sampleRatio>1</sampleRatio>
        </search>
        <option name="count">20</option>
        <option name="dataOverlayMode">none</option>
        <option name="drilldown">cell</option>
        <option name="percentagesRow">false</option>
        <option name="rowNumbers">true</option>
        <option name="totalsRow">false</option>
        <option name="wrap">true</option>
        <format type="color" field="status">
          <colorPalette type="map">{"online":#65A637,"offline":#D93F3C}</colorPalette>
        </format>
        <format type="color" field="last_online">
          <colorPalette type="map">{"-":#FFFFFF}</colorPalette>
        </format>
      </table>
    </panel>
  </row>
  <row>
    <panel>
      <title>Liste des index et de leurs tailles</title>
      <table id="table1">
        <search>
          <query>***</query>
          <earliest>@d</earliest>
          <latest>now</latest>
          <sampleRatio>1</sampleRatio>
        </search>
        <option name="count">20</option>
        <option name="dataOverlayMode">none</option>
        <option name="drilldown">cell</option>
        <option name="percentagesRow">false</option>
        <option name="rowNumbers">true</option>
        <option name="totalsRow">false</option>
        <option name="wrap">true</option>
      </table>
    </panel>
    <panel>
      <title>Vérification de la date d'indexation</title>
      <table id="table2">
        <search>
          <query>***</query>
          <earliest>0</earliest>
          <latest></latest>
          <sampleRatio>1</sampleRatio>
        </search>
        <option name="count">20</option>
        <option name="dataOverlayMode">none</option>
        <option name="drilldown">cell</option>
        <option name="percentagesRow">false</option>
        <option name="rowNumbers">true</option>
        <option name="totalsRow">false</option>
        <option name="wrap">true</option>
      </table>
    </panel>
  </row>
  <row>
    <panel>
      <title>Maj du fichier des cvss</title>
      <table id="table3">
        <search>
          <query>***</query>
          <earliest>0</earliest>
          <sampleRatio>1</sampleRatio>
        </search>
        <option name="count">20</option>
        <option name="dataOverlayMode">none</option>
        <option name="drilldown">cell</option>
        <option name="percentagesRow">false</option>
        <option name="rowNumbers">true</option>
        <option name="totalsRow">false</option>
        <option name="wrap">true</option>
      </table>
    </panel>
  </row>
  <row>
    <panel>
      <title>Etat des sites de Qualys</title>
      <table id="table4">
        <search>
          <query>***</query>
          <earliest>@d</earliest>
          <latest>now</latest>
          <sampleRatio>1</sampleRatio>
        </search>
        <option name="count">20</option>
        <option name="dataOverlayMode">none</option>
        <option name="drilldown">cell</option>
        <option name="percentagesRow">false</option>
        <option name="rowNumbers">true</option>
        <option name="totalsRow">false</option>
        <option name="wrap">true</option>
      </table>
    </panel>
  </row>
</dashboard><dashboard script="cell_fill_gauge.js, table_icons_rangemap.js" stylesheet="table_decorations.css">
  <label>Surveillance</label>
  <row>
    <panel>
      <title>Disk Usage</title>
      <table id="disk_usage">
        <search>
          <query>***</query>
          <sampleRatio>1</sampleRatio>
        </search>
        <option name="count">10</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>
        <format type="number" field="Disk Usage (GB)"></format>
      </table>
    </panel>
  </row>
  <row>
    <panel>
      <title>Indexes</title>
      <table id="indexes">
        <search>
          <query>***</query>
          <earliest>$earliest$</earliest>
          <latest>$latest$</latest>
          <sampleRatio>1</sampleRatio>
        </search>
        <option name="count">20</option>
        <option name="dataOverlayMode">none</option>
        <option name="drilldown">cell</option>
        <option name="percentagesRow">false</option>
        <option name="rowNumbers">true</option>
        <option name="totalsRow">false</option>
        <option name="wrap">true</option>
      </table>
    </panel>
  </row>
  <row>
    <panel>
      <title>Etat des sondes</title>
      <table>
        <search>
          <query>***</query>
          <earliest>0</earliest>
          <sampleRatio>1</sampleRatio>
        </search>
        <option name="count">20</option>
        <option name="dataOverlayMode">none</option>
        <option name="drilldown">cell</option>
        <option name="percentagesRow">false</option>
        <option name="rowNumbers">true</option>
        <option name="totalsRow">false</option>
        <option name="wrap">true</option>
        <format type="color" field="status">
          <colorPalette type="map">{"online":#65A637,"offline":#D93F3C}</colorPalette>
        </format>
        <format type="color" field="last_online">
          <colorPalette type="map">{"-":#FFFFFF}</colorPalette>
        </format>
      </table>
    </panel>
  </row>
  <row>
    <panel>
      <title>Liste des index et de leurs tailles</title>
      <table id="table1">
        <search>
          <query>***</query>
          <earliest>@d</earliest>
          <latest>now</latest>
          <sampleRatio>1</sampleRatio>
        </search>
        <option name="count">20</option>
        <option name="dataOverlayMode">none</option>
        <option name="drilldown">cell</option>
        <option name="percentagesRow">false</option>
        <option name="rowNumbers">true</option>
        <option name="totalsRow">false</option>
        <option name="wrap">true</option>
      </table>
    </panel>
    <panel>
      <title>Vérification de la date d'indexation</title>
      <table id="table2">
        <search>
          <query>***</query>
          <earliest>0</earliest>
          <latest></latest>
          <sampleRatio>1</sampleRatio>
        </search>
        <option name="count">20</option>
        <option name="dataOverlayMode">none</option>
        <option name="drilldown">cell</option>
        <option name="percentagesRow">false</option>
        <option name="rowNumbers">true</option>
        <option name="totalsRow">false</option>
        <option name="wrap">true</option>
      </table>
    </panel>
  </row>
  <row>
    <panel>
      <title>Maj du fichier des cvss</title>
      <table id="table3">
        <search>
          <query>***</query>
          <earliest>0</earliest>
          <sampleRatio>1</sampleRatio>
        </search>
        <option name="count">20</option>
        <option name="dataOverlayMode">none</option>
        <option name="drilldown">cell</option>
        <option name="percentagesRow">false</option>
        <option name="rowNumbers">true</option>
        <option name="totalsRow">false</option>
        <option name="wrap">true</option>
      </table>
    </panel>
  </row>
  <row>
    <panel>
      <title>Etat des sites de Qualys</title>
      <table id="table4">
        <search>
          <query>***</query>
          <earliest>@d</earliest>
          <latest>now</latest>
          <sampleRatio>1</sampleRatio>
        </search>
        <option name="count">20</option>
        <option name="dataOverlayMode">none</option>
        <option name="drilldown">cell</option>
        <option name="percentagesRow">false</option>
        <option name="rowNumbers">true</option>
        <option name="totalsRow">false</option>
        <option name="wrap">true</option>
      </table>
    </panel>
  </row>
</dashboard>

Javascript - table_icons_rangemap.js

require([
    'underscore',
    'jquery',
    'splunkjs/mvc',
    'splunkjs/mvc/tableview',
    'splunkjs/mvc/simplexml/ready!'
], function(_, $, mvc, TableView) {
    // Translations from rangemap results to CSS class
    var ICONS = {
        red: 'alert-circle',
        orange: 'alert',
        green: 'check-circle'
    };
    var RangeMapIconRenderer = TableView.BaseCellRenderer.extend({
        canRender: function(cell) {
            // Only use the cell renderer for the range field
            return cell.field === 'range';
        },
        render: function($td, cell) {
            var icon = 'question';
            // Fetch the icon for the value
            if (ICONS.hasOwnProperty(cell.value)) {
                icon = ICONS[cell.value];
            }
            // Create the icon element and add it to the table cell
            $td.addClass('icon').html(_.template('<i class="icon-<%-icon%> <%- range %>" title="<%- range %>"></i>', {
                icon: icon,
                range: cell.value
            }));
        }
    });

    mvc.Components.get('table1').getVisualization(function(tableView){
        // Register custom cell renderer
        tableView.addCellRenderer(new RangeMapIconRenderer());
    });


    mvc.Components.get('table2').getVisualization(function(tableView){
        // Register custom cell renderer
        tableView.addCellRenderer(new RangeMapIconRenderer());       
    });

    mvc.Components.get('table3').getVisualization(function(tableView){
         // Register custom cell renderer
        tableView.addCellRenderer(new RangeMapIconRenderer());
    });

   mvc.Components.get('table4').getVisualization(function(tableView){
         // Register custom cell renderer
        tableView.addCellRenderer(new RangeMapIconRenderer());
    });


});
0 Karma

niketn
Legend

@Mahilde, it worked for me for 4 tables as well. Can you load dashboard without cell_fill_gauge.js and see?
If the Dashboards JS is not being applied correctly, you might to test with browser's Console log to test whether there is any JS error logged.

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

Mathilde
Explorer

@niketn, I loaded the dashboard without the cell_fill_gauge.js.
But, I have the same problem.

I see that a warning appears when I refresh the page before it's fully displayed : Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience.

After a few searches, I see in /opt/splunk/share/splunk/search_mrsparkle/exposed/build/pages/enterprise/common.js : "async:!0".

But, I don't think this is the problem

0 Karma

niketn
Legend

Three table works just fine for me (refer to attached screenshot).

alt text

  1. You need to ensure table id is the same in Simple XML and JS i.e. table1, table2 and table2.
  2. After editing your Simple XML dashboard, you need to refresh your Dashboard for the first time.
  3. Also make sure you bump Splunk server and clear Browser history.
  4. Finally, use Browser inspect tool to ensure there are no JavaScript errors in Console logs.

Simple XML - Notice Table IDs table1, table2 and table3

<dashboard script="table_icons_rangemap.js" stylesheet="table_decorations.css">
  <label>Table Icon Rangemap</label>
  <description>Use Javascript and CSS in tables to convert rangemap results into icons.</description>
  <row>
    <panel>
      <table id="table1">
        <title>Render Icons based on rangemap result</title>
        <search>
          <query>index=_internal
                    | stats count by sourcetype,source
                    | rangemap field=count low=0-100 elevated=101-1000 default=severe</query>
          <earliest>-1h</earliest>
        </search>
        <option name="drilldown">none</option>
      </table>
    </panel>
    <panel>
      <table id="table2">
        <title>Render Icons based on rangemap result</title>
        <search>
          <query>index=_internal
                    | stats count by sourcetype,source
                    | rangemap field=count low=0-100 elevated=101-1000 default=severe</query>
          <earliest>-1h</earliest>
        </search>
        <option name="drilldown">none</option>
      </table>
    </panel>
    <panel>
      <table id="table3">
        <title>Render Icons based on rangemap result</title>
        <search>
          <query>index=_internal
                    | stats count by sourcetype,source
                    | rangemap field=count low=0-100 elevated=101-1000 default=severe</query>
          <earliest>-1h</earliest>
        </search>
        <option name="drilldown">none</option>
      </table>
    </panel>
  </row>
</dashboard>

JavaScript - Separate invocation for table1, table2 and table3

require([
    'underscore',
    'jquery',
    'splunkjs/mvc',
    'splunkjs/mvc/tableview',
    'splunkjs/mvc/simplexml/ready!'
], function(_, $, mvc, TableView) {
    // Translations from rangemap results to CSS class
    var ICONS = {
        severe: 'alert-circle',
        elevated: 'alert',
        low: 'check-circle'
    };
    var RangeMapIconRenderer = TableView.BaseCellRenderer.extend({
        canRender: function(cell) {
            // Only use the cell renderer for the range field
            return cell.field === 'range';
        },
        render: function($td, cell) {
            var icon = 'question';
            // Fetch the icon for the value
            if (ICONS.hasOwnProperty(cell.value)) {
                icon = ICONS[cell.value];
            }
            // Create the icon element and add it to the table cell
            $td.addClass('icon').html(_.template('<i class="icon-<%-icon%> <%- range %>" title="<%- range %>"></i>', {
                icon: icon,
                range: cell.value
            }));
        }
    });
    mvc.Components.get('table1').getVisualization(function(tableView){
        // Register custom cell renderer, the table will re-render automatically
        tableView.addCellRenderer(new RangeMapIconRenderer());
    });
    mvc.Components.get('table2').getVisualization(function(tableView){
        // Register custom cell renderer, the table will re-render automatically
        tableView.addCellRenderer(new RangeMapIconRenderer());
    });
    mvc.Components.get('table3').getVisualization(function(tableView){
        // Register custom cell renderer, the table will re-render automatically
        tableView.addCellRenderer(new RangeMapIconRenderer());
    });
});

No Changes to CSS provided in Simple XML Examples for Table Icon Set(Rangemap) example.

If you still face the issue you might have to post XML and JS code snippet from your use case. Please make sure while posting the code you use Code button (101010).

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

koshyk
Super Champion

Cant you use the inbuilt rangemap icons? it is very easy to setup and supported by Splunk
You can have a play with https://splunkbase.splunk.com/app/1603/

0 Karma

Mathilde
Explorer

I did that.
The code I posted is a code of table_icon_rangemap.js which was in Splunk 6.x Dashboard Examples

0 Karma
Get Updates on the Splunk Community!

Routing logs with Splunk OTel Collector for Kubernetes

The Splunk Distribution of the OpenTelemetry (OTel) Collector is a product that provides a way to ingest ...

Welcome to the Splunk Community!

(view in My Videos) We're so glad you're here! The Splunk Community is place to connect, learn, give back, and ...

Tech Talk | Elevating Digital Service Excellence: The Synergy of Splunk RUM & APM

Elevating Digital Service Excellence: The Synergy of Real User Monitoring and Application Performance ...