Dashboards & Visualizations

How to dynamically increase the panel based on multiselect

sangs8788
Communicator

I have a multiselect box which is getting populated with Release numbers

  <label>Release(s)</label>
  <search>
    <query>|inputlookup ReleaseCalender.csv |sort Release DESC | table Release</query>
  </search>
  <fieldForLabel>Release</fieldForLabel>
  <fieldForValue>Release</fieldForValue>
  <prefix>(</prefix>
  <valuePrefix>Release ="</valuePrefix>
  <valueSuffix>"</valueSuffix>
  <delimiter> OR </delimiter>
  <suffix>)</suffix>
</input>

The query here is how to add panels based on selection ? Since the mulitselect is also populated dynamically, how do i assign the selection with individual panels. Consider at any point of time i can only select 5 releases, I need 5 individual for each selected release.

For example
The multiselect lists , 7.3, 7.2, 7.1, 7.0 etc
My selection is 7.3 and 7.1, I would need two different panels to be displayed for each release. How do we achieve this ?
Also I would need the Release number selected to be appeared as panel title.

Tags (1)
1 Solution

niketn
Legend

@sangs8788, here is the option with Dynamic Panels (independent of Version). As earlier this has been created for three panels, please convert accordingly for five panels.

<form>
  <label>Multiselect Show/Hide Panel Dynamic Option</label>
  <search>
    <query>| makeresults
| eval multiSelect="$tokRelease$"
| eval multiSelect=split(multiSelect," OR ")
| rex field=multiSelect "Release=(?<Release>.*)"
| eval inputCounter=mvcount(Release)
| eval Panel1=mvindex(Release,0)
| eval Panel2=mvindex(Release,1)
| eval Panel3=mvindex(Release,2)
| table inputCounter Panel1 Panel2 Panel3
    </query>
    <progress>
      <condition match="isnotnull($result.inputCounter$)">
        <eval token="tokPanel1">case(($result.inputCounter$=="1" OR $result.inputCounter$=="2" OR $result.inputCounter$=="3"),$result.Panel1$)</eval>
        <eval token="tokPanel2">case(($result.inputCounter$=="2" OR $result.inputCounter$=="3"),$result.Panel2$)</eval>
        <eval token="tokPanel3">case($result.inputCounter$=="3",$result.Panel3$)</eval>
      </condition>
    </progress>
  </search>
  <fieldset submitButton="false">
    <input type="multiselect" token="tokRelease" searchWhenChanged="true">
      <label>Release(s)</label>
      <valuePrefix>Release=</valuePrefix>
      <valueSuffix></valueSuffix>
      <delimiter> OR </delimiter>
      <fieldForLabel>Release</fieldForLabel>
      <fieldForValue>Release</fieldForValue>
      <search>
        <query>|inputlookup ReleaseCalendar.csv
| sort Release DESC 
| table Release</query>
        <earliest>-24h@h</earliest>
        <latest>now</latest>
      </search>
      <change>
        <condition match="isnull(value)">
          <!-- Unset All Tokens/Hide all panels when Nothing is selected -->
          <unset token="tokPanel1"></unset>
          <unset token="tokPanel2"></unset>
          <unset token="tokPanel3"></unset>          
        </condition>
      </change>
    </input>
  </fieldset>
  <row>
    <panel depends="$tokPanel1$">
      <single>
        <search>
          <query>| makeresults
            | eval Release="$tokPanel1$"
            | table Release
          </query>
        </search>
        <option name="numberPrecision">0.0</option>
      </single>
    </panel>
    <panel depends="$tokPanel2$">
      <single>
        <search>
          <query>| makeresults
            | eval Release="$tokPanel2$"
            | table Release
          </query>
        </search>
        <option name="numberPrecision">0.0</option>
      </single>
    </panel>
    <panel depends="$tokPanel3$">
      <single>
        <search>
          <query>| makeresults
            | eval Release="$tokPanel3$"
            | table Release
          </query>
        </search>
        <option name="numberPrecision">0.0</option>
      </single>
    </panel>
  </row>
</form>
____________________________________________
| makeresults | eval message= "Happy Splunking!!!"

View solution in original post

niketn
Legend

@sangs8788, here is the option with Dynamic Panels (independent of Version). As earlier this has been created for three panels, please convert accordingly for five panels.

<form>
  <label>Multiselect Show/Hide Panel Dynamic Option</label>
  <search>
    <query>| makeresults
| eval multiSelect="$tokRelease$"
| eval multiSelect=split(multiSelect," OR ")
| rex field=multiSelect "Release=(?<Release>.*)"
| eval inputCounter=mvcount(Release)
| eval Panel1=mvindex(Release,0)
| eval Panel2=mvindex(Release,1)
| eval Panel3=mvindex(Release,2)
| table inputCounter Panel1 Panel2 Panel3
    </query>
    <progress>
      <condition match="isnotnull($result.inputCounter$)">
        <eval token="tokPanel1">case(($result.inputCounter$=="1" OR $result.inputCounter$=="2" OR $result.inputCounter$=="3"),$result.Panel1$)</eval>
        <eval token="tokPanel2">case(($result.inputCounter$=="2" OR $result.inputCounter$=="3"),$result.Panel2$)</eval>
        <eval token="tokPanel3">case($result.inputCounter$=="3",$result.Panel3$)</eval>
      </condition>
    </progress>
  </search>
  <fieldset submitButton="false">
    <input type="multiselect" token="tokRelease" searchWhenChanged="true">
      <label>Release(s)</label>
      <valuePrefix>Release=</valuePrefix>
      <valueSuffix></valueSuffix>
      <delimiter> OR </delimiter>
      <fieldForLabel>Release</fieldForLabel>
      <fieldForValue>Release</fieldForValue>
      <search>
        <query>|inputlookup ReleaseCalendar.csv
| sort Release DESC 
| table Release</query>
        <earliest>-24h@h</earliest>
        <latest>now</latest>
      </search>
      <change>
        <condition match="isnull(value)">
          <!-- Unset All Tokens/Hide all panels when Nothing is selected -->
          <unset token="tokPanel1"></unset>
          <unset token="tokPanel2"></unset>
          <unset token="tokPanel3"></unset>          
        </condition>
      </change>
    </input>
  </fieldset>
  <row>
    <panel depends="$tokPanel1$">
      <single>
        <search>
          <query>| makeresults
            | eval Release="$tokPanel1$"
            | table Release
          </query>
        </search>
        <option name="numberPrecision">0.0</option>
      </single>
    </panel>
    <panel depends="$tokPanel2$">
      <single>
        <search>
          <query>| makeresults
            | eval Release="$tokPanel2$"
            | table Release
          </query>
        </search>
        <option name="numberPrecision">0.0</option>
      </single>
    </panel>
    <panel depends="$tokPanel3$">
      <single>
        <search>
          <query>| makeresults
            | eval Release="$tokPanel3$"
            | table Release
          </query>
        </search>
        <option name="numberPrecision">0.0</option>
      </single>
    </panel>
  </row>
</form>
____________________________________________
| makeresults | eval message= "Happy Splunking!!!"

niketn
Legend

@sangs8788, please test this and confirm.

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

sangs8788
Communicator

WIll check and let you know. Thanks.

0 Karma

niketn
Legend

@sangs8788, Mutiselect input's change event handler is not enabled to handle multiple values (there are some previous question with multi-select and even check boxes with this issue and has not been resolved yet). Hence you would need some workaround.

Following is your option with multi-select which uses a dummy search to set the required token/s. I have uploaded a dummy ReleaseCalendar.csv (notice the spelling change as compared to your sample code, please correct accordingly). For the example I have set only three panels for Release versions 7.4, 7.3 and 7.2 (you would need to set as many as you need and as per your use case).

alt text

One of the changes to multiselect input Dynamic Query is that I have changed Token prefix and Token suffix to be without double quotes (for simplicity of query to handle the Release extraction from token in dummy search later). Since Releases are numeric, you should still be fine with your existing queries based on Multiselect token.

  <valuePrefix>Release=</valuePrefix>
  <valueSuffix></valueSuffix>
  <delimiter> OR </delimiter>

If no value is selected (or all values are removed in the Multiselect input, then all Panel are hidden by unsetting the tokens in change event handler (this works for multivalued input :))

  <change>
    <condition match="isnull(value)">
      <!-- Unset All Tokens/Hide all panels when Nothing is selected -->
      <unset token="tokPanel7_4"></unset>
      <unset token="tokPanel7_3"></unset>
      <unset token="tokPanel7_2"></unset>          
    </condition>
  </change>

Following is a dummy search which taken the input as Multiselect token and splits them to generate Release/s as multivalue field called Release. PS: I have replaced the token with a sample string below in second pipe with eval for testing query:

| makeresults
| eval multiSelect="Release=7.4 OR Release=7.3 OR Release=7.2"
| eval multiSelect=split(multiSelect," OR ")
| rex field=multiSelect "Release=(?<Release>.*)"
| table Release

Finally, dummy Search's progress event handler is used to unset all tokens for displaying panels and then only the panels for selected Releases are set (PS: As stated earlier I have coded only three panels, you would need to add more):

 <progress>
  <!-- Ideally this condition should not be hit -->
  <condition match="$job.resultCount$==0">
    <!-- Unset All Tokens/Hide all panels when Release Token is not set -->
      <unset token="tokPanel7_4"></unset>
      <unset token="tokPanel7_3"></unset>
      <unset token="tokPanel7_2"></unset> 
  </condition>
  <condition>
    <unset token="tokPanel7_4"></unset>
    <unset token="tokPanel7_3"></unset>
    <unset token="tokPanel7_2"></unset>
    <eval token="tokPanel7_4">case(match($result.Release$,"7.4"),"7.4")</eval>
    <eval token="tokPanel7_3">case(match($result.Release$,"7.3"),"7.3")</eval>
    <eval token="tokPanel7_2">case(match($result.Release$,"7.2"),"7.2")</eval>
  </condition>
</progress>

Following is the complete code of the dummy dashboard discussed here for reference:

<form>
  <label>Multiselect Show/Hide Panel</label>
  <search>
    <query>| makeresults
| eval multiSelect="$tokRelease$"
| eval multiSelect=split(multiSelect," OR ")
| rex field=multiSelect "Release=(?<Release>.*)"
| table Release
    </query>
    <progress>
      <condition match="$job.resultCount$==0">
        <!-- Ideally this condition should not be hit -->
        <!-- Unset All Tokens/Hide all panels when Release Token is not set -->
          <unset token="tokPanel7_4"></unset>
          <unset token="tokPanel7_3"></unset>
          <unset token="tokPanel7_2"></unset> 
      </condition>
      <condition>
        <unset token="tokPanel7_4"></unset>
        <unset token="tokPanel7_3"></unset>
        <unset token="tokPanel7_2"></unset>
        <eval token="tokPanel7_4">case(match($result.Release$,"7.4"),"7.4")</eval>
        <eval token="tokPanel7_3">case(match($result.Release$,"7.3"),"7.3")</eval>
        <eval token="tokPanel7_2">case(match($result.Release$,"7.2"),"7.2")</eval>
      </condition>
    </progress>
  </search>
  <fieldset submitButton="false">
    <input type="multiselect" token="tokRelease" searchWhenChanged="true">
      <label>Release(s)</label>
      <valuePrefix>Release=</valuePrefix>
      <valueSuffix></valueSuffix>
      <delimiter> OR </delimiter>
      <fieldForLabel>Release</fieldForLabel>
      <fieldForValue>Release</fieldForValue>
      <search>
        <query>|inputlookup ReleaseCalendar.csv
| sort Release DESC 
| table Release</query>
        <earliest>-24h@h</earliest>
        <latest>now</latest>
      </search>
      <change>
        <condition match="isnull(value)">
          <!-- Unset All Tokens/Hide all panels when Nothing is selected -->
          <unset token="tokPanel7_4"></unset>
          <unset token="tokPanel7_3"></unset>
          <unset token="tokPanel7_2"></unset>          
        </condition>
      </change>
    </input>
  </fieldset>
  <row>
    <panel depends="$tokPanel7_4$">
      <single>
        <search>
          <query>| makeresults
            | eval Release="$tokPanel7_4$"
            | table Release
          </query>
        </search>
        <option name="numberPrecision">0.0</option>
      </single>
    </panel>
    <panel depends="$tokPanel7_3$">
      <single>
        <search>
          <query>| makeresults
            | eval Release="7.3"
            | table Release
          </query>
        </search>
        <option name="numberPrecision">0.0</option>
      </single>
    </panel>
    <panel depends="$tokPanel7_2$">
      <single>        
        <search>
          <query>| makeresults
            | eval Release="7.2"
            | table Release
          </query>
        </search>
        <option name="numberPrecision">0.0</option>
      </single>
    </panel>    
  </row>
</form>

Please try out and confirm.

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

sangs8788
Communicator

This would work considering the Release to be always 7.4, 7.3 and 7.2. How do i automate it no matter what the release number is going to be. Say in future i will have 8.1, 8.2 etc. In that case this wouldnt work. Is there a way to assign resultset value 1 to assign to a panel, resultset value 2 to assign to a panel, etc ?

0 Karma

niketn
Legend

@sangs8788, what you are asking will require us to know what query you are using in the panel. Only if that can be made dynamic based on multiselect input, then we can link first value selected to first panel and so on.

Current code as you can see has static panels and whichever sequence you choose multiple Inputs the panels are still visible. Please provide the complete query for your panel so that we can see whether dynamic query is possible or not.

Alternatively you can have hidden panels for future releases set upfront they will be displayed only when the version becomes available in your Release lookup file.

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

sangs8788
Communicator

To your question used on the panel can be made dynamic. The query would return me the errors in the release. Below is the query to be used in the panel

index=app host="prod*" ERROR $release_timerange$

The token $release_timerange$ value would be something like "earliest=1598753 latest=1609347". It is got using below query

<query>|inputlookup ReleaseCalender.csv |sort Release ASC  | reverse |streamstats current=f last(Production) as latest|rename Production as earliest|eval timenow=now()| convert mktime(*) timeformat="%d/%m/%Y"| where earliest&lt;timenow AND latest&gt;=timenow | table earliest, latest| format "" "" "" "" "" ""| rex field=search mode=sed "s/\"//g" |fields search</query>
<finalized>
  <set token="release_timerange">$result.search$</set>
</finalized>
0 Karma

sangs8788
Communicator

@niketnilay Is this something which can be done ? Please let me know

0 Karma

niketn
Legend

@sangs8788, I have already answered this as a separate answer here with dynamic option. It is based on three panels which you can extend to 5.

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

sangs8788
Communicator

The code you shared still doesnt seems to work for me. I copied over your code and created a dashboard. I believe token tokPanel is not getting set. Is there anything in this code not supported for hte version 6.4.2 ?

0 Karma

niketn
Legend

Change search event handler from <progress> to <preview> if you are on 6.4.2

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

woodcock
Esteemed Legend

If you need to dynamically instantiate dashboard panels then you have 2 options:
Trellis: https://docs.splunk.com/Documentation/SplunkCloud/6.6.1/Viz/VisualizationTrellis
Sideview Utils multplexer: https://sideviewapps.com/apps/sideview-utils/download-full-version-internal-use/

0 Karma

woodcock
Esteemed Legend

Perhaps @sideview will comment.

sideview
SplunkTrust
SplunkTrust

Getting some disclaimers out of the way -- Sideview XML is a different way of thinking about it, and a whole other system to learn. Although basically everything from a simple xml dashboard has some equivalent in Sideview XML, there's no conversion utility and the best advice is to read all the docs and working examples inside Sideview Utils itself (60+ pages of docs and living working examples), and work your way up from simple examples to complex ones.

The Multiplexer module is definitely on the "complex examples" side. The short version is that Sideview UI modules are little things like "Pulldown" or "Table" or "Pager" or "HTML" or "Search". You string modules together, and the framework figures out which searches you need dispatched for which modules, and how to pass all the little $foo$ tokens around so everyone gets what they need.

You don't write code, but you either write the XML raw, or use the Sideview Editor, which is a little clunky but which is a full authoring tool for the format.

MULTIPLEXER then, is an extremely powerful module - you configure it with one branch of modules downstream from it - which can be practically any set of modules. And it looks at the search results it's given, and it then creates one copy of that branch of modules ,for each row it sees in the search results.

So effectively you can end up with one "paged table with a postprocess" for each row in an upstream search. Generally what is multiplexed 90% of the time is "a single HTML module" which is still super powerful.... And on the extreme end there isn't really an upper bound. You can multiplex module config using JSCharts, Tables, drlldown config, even other Multiplexer modules.

Note - you can only download the real Sideview Utils here -
https://sideviewapps.com/apps/sideview-utils/

0 Karma

rjthibod
Champion

You can use the new Trellis chart feature in Splunk if you are running version 6.6. Here is the documentation link: https://docs.splunk.com/Documentation/Splunk/latest/Viz/VisualizationTrellis

Things get a lot trickier if you running earlier than version 6.6.

0 Karma
Get Updates on the Splunk Community!

Index This | I am a number, but when you add ‘G’ to me, I go away. What number am I?

March 2024 Edition Hayyy Splunk Education Enthusiasts and the Eternally Curious!  We’re back with another ...

What’s New in Splunk App for PCI Compliance 5.3.1?

The Splunk App for PCI Compliance allows customers to extend the power of their existing Splunk solution with ...

Extending Observability Content to Splunk Cloud

Register to join us !   In this Extending Observability Content to Splunk Cloud Tech Talk, you'll see how to ...