Modify and write dynamic options syntax
The following examples demonstrate how you can modify dynamic options syntax (DOS) in the source code to dynamically update dashboards.
Add to existing DOS in the source code
You need to write your own DOS in the source code editor for advanced uses, but it is more efficient to start with pre-generated DOS in the source code editor before writing new DOS. You can set as many dynamic options as possible in the UI, which populates the source code with DOS, then add or modify configurations as needed.
The following examples apply dynamic coloring using DOS by starting with pre-generated DOS created from the visual editor UI and editing that DOS with manual adjustments.
Example: applying dynamic coloring to a table column based on another column's values
Using DOS, you can dynamically color a cell or column in a table based on values in another column. The following example represents a table with 2 columns: Game and Purchases. You want to dynamically update the text colors of the Game column based on values in the Purchases column.
To configure this, you first apply dynamic coloring based on the values in the Purchases column for the Purchases column itself in the UI. Then, you manually modify the DOS to apply the dynamic coloring to the Game column.
First, set 5 color thresholds by selecting the table, then under Color and style, selecting Column-specific formatting and then selecting Purchases - number:
- Green: more than 2,400 purchases
- Light green: 2,200 to 2,400 purchases
- Yellow: 2,000 to 2,200 purchases
- Orange: 1,700 to 2,000 purchases
- Red: fewer than 1,700 purchases
The following shows the table after applying dynamic coloring based on the values in the Purchases column to the Purchases column itself.
Now, select Source code in the configuration panel to see the source code for the table visualization. The following code is within the options section of the source code:
"options": {
"columnFormat": {
"Purchases": {
"data": "> table | seriesByName(\"Purchases\") | formatByType(PurchasesColumnFormatEditorConfig)",
"align": "auto",
"headerAlign": "auto",
"textOverflow": "break-word",
"rowColors": "> table | seriesByName(\"Purchases\") | rangeValue(PurchasesRowColorsEditorConfig)"
}
}
},
In this example, the following line of DOS defines the rowColors value of the column Purchases:
"rowColors": "> table | seriesByName(\"Purchases\") | rangeValue(PurchasesRowColorsEditorConfig)"
The selector function in this line, seriesByName, selects the Purchases column. The rangeValue function uses the input PurchasesRowColorsEditorConfig to format the values in the column Purchases.
The definition of PurchasesRowColorsEditorConfig is in the context section of the source code, which parallels the configuration in the UI, coloring values above 2,400 green, values between 2,200 and 2,400 light green, and so on:
"context": {
"PurchasesColumnFormatEditorConfig": {
"number": {
"thousandSeparated": false,
"unitPosition": "after"
}
},
"PurchasesRowColorsEditorConfig": [
{
"value": "#D41F1F",
"to": 1700
},
{
"value": "#D94E17",
"from": 1700,
"to": 2000
},
{
"value": "#CBA700",
"from": 2000,
"to": 2200
},
{
"value": "#669922",
"from": 2200,
"to": 2400
},
{
"value": "#118832",
"from": 2400
}
]
},
Now you can modify the PurchasesRowColorsEditorConfig values to dynamically color the Game column instead of the Purchases column. To achieve this, you remove the line of DOS that defines rowColors from the Purchases sub-stanza and paste it in the Game sub-stanza. If your Game column currently only has default options configured, you need to also add the Game sub-stanza under columnFormat.
These edits result in the following code in the options section:
"options": {
"columnFormat": {
"Purchases": {
"data": "> table | seriesByName(\"Purchases\") | formatByType(PurchasesColumnFormatEditorConfig)",
"align": "auto",
"headerAlign": "auto",
"textOverflow": "break-word"
},
"Game":{
"rowColors": "> table | seriesByName(\"Purchases\") | rangeValue(PurchasesRowColorsEditorConfig)"
}
}
},
In this new code, the rowColors option for the Game column is defined by the following line of DOS:
"> table | seriesByName(\"Purchases\") | rangeValue(PurchasesRowColorsEditorConfig)"
This line of DOS results in the desired dynamic coloring in the chart. Now, each individual game title in the Game column is colored by its corresponding value within the same row in the Purchases column.
Copy and paste the dashboard definition into your own dashboard to see the example:
{
"title": "Dynamic coloring based on another table column example",
"description": "",
"inputs": {
"input_global_trp": {
"options": {
"defaultValue": "-24h@h,now",
"token": "global_time"
},
"title": "Global Time Range",
"type": "input.timerange"
}
},
"defaults": {
"dataSources": {
"ds.search": {
"options": {
"queryParameters": {
"earliest": "$global_time.earliest$",
"latest": "$global_time.latest$"
}
}
}
},
"visualizations": {
"global": {
"showProgressBar": true
}
}
},
"visualizations": {
"viz_JvmfYGrl": {
"context": {
"PurchasesColumnFormatEditorConfig": {
"number": {
"thousandSeparated": false,
"unitPosition": "after"
}
},
"PurchasesRowColorsEditorConfig": [
{
"to": 1700,
"value": "#D41F1F"
},
{
"from": 1700,
"to": 2000,
"value": "#D94E17"
},
{
"from": 2000,
"to": 2200,
"value": "#CBA700"
},
{
"from": 2200,
"to": 2400,
"value": "#669922"
},
{
"from": 2400,
"value": "#118832"
}
]
},
"dataSources": {
"primary": "ds_yUVJ8eQR"
},
"options": {
"columnFormat": {
"Game": {
"rowColors": "> table | seriesByName(\"Purchases\") | rangeValue(PurchasesRowColorsEditorConfig)"
},
"Purchases": {
"align": "auto",
"data": "> table | seriesByName(\"Purchases\") | formatByType(PurchasesColumnFormatEditorConfig)",
"headerAlign": "auto",
"textOverflow": "break-word"
}
}
},
"type": "splunk.table"
}
},
"dataSources": {
"ds_yUVJ8eQR": {
"name": "Game purchases data",
"options": {
"query": "| makeresults count=10\n| streamstats count\n| eval Game=case(\n count=1, \"Nebula Knights\", \n count=2, \"Shadow Protocol\", \n count=3, \"Cyber Drifter\", \n count=4, \"Mana Quest\", \n count=5, \"Void Runner\", \n count=6, \"Star Forge\", \n count=7, \"Echoes of Aegis\", \n count=8, \"Titan Fallback\", \n count=9, \"Neon Nexus\", \n count=10, \"Aether Blade\"\n )\n| eval Purchases = 1000 + (random() % 1501)\n| table Game Purchases"
},
"type": "ds.search"
}
},
"layout": {
"globalInputs": [
"input_global_trp"
],
"layoutDefinitions": {
"layout_1": {
"options": {
"height": 960,
"width": 1440
},
"structure": [
{
"item": "viz_JvmfYGrl",
"position": {
"h": 410,
"w": 830,
"x": 390,
"y": 30
},
"type": "block"
}
],
"type": "absolute"
}
},
"options": {},
"tabs": {
"items": [
{
"label": "Overview",
"layoutId": "layout_1"
}
]
}
}
}Example: coloring a single value visualization sparkline
In Dashboard Studio, you can add a sparkline to a single value visualization using the timechart command in your search. See Single value visualizations to learn more about the timechart command and how to add sparklines to your visualizations.
Using DOS, you can dynamically color a sparkline based on the trend value in the single value visualization to which you attached the sparkline. To configure this, you first apply dynamic coloring to the trend value in the UI. Then, you manually modify the DOS to apply the dynamic coloring to the sparkline.
First, configure the dynamic coloring for the trend value. Select the single value visualization, then under Color and style in the Configuration panel, select Trend value from the Dynamic elements dropdown. By default, the trend value is colored green for positive numbers and red for negative numbers.
The following example represents a single value visualization of all Buttercup Games purchases in the category Arcade within the past 2 days.
Now open Source code in the configuration panel to see the source code for the visualization. The following code is in the options section of the source code:
"options": {
"trendColor": "> trendValue | rangeValue(trendColorEditorConfig)"
},
To color the sparkline, you need to set the option that defines the sparkline color, sparklineStrokeColor. Since the trendColor option already contains all the formatting necessary for the sparkline's color, you can reference trendColor when defining the sparklineStrokeColor option. See Single value visualizations for a full list of source options for single value visualizations.
In the options section, the formatting function defining the trendColor value is rangeValue, and the input for that function is trendColorEditorConfig. The following code within the context section of the source code defines trendColorEditorConfig:
"context": {
"trendColorEditorConfig": [
{
"to": 0,
"value": "#9E2520"
},
{
"from": 0,
"value": "#1C6B2D"
}
]
}
To define the sparklineStrokeColor value, you only need to provide a data source, because trendColor already contains a selector function. Based on the definition of trendColor, add the line of code "sparklineStrokeColor": "> trendColor" to the start of the options section. This results in the following edited code under the options section:
"options": {
"sparklineStrokeColor": "> trendColor",
"trendColor": "> trendValue | rangeValue(trendColorEditorConfig)"
},
The line of DOS that you added results in the correct dynamic coloring result. Now, the sparkline under the single value visualization is colored by its corresponding trend value. The following screenshot shows the sparkline after editing the DOS for the single value visualization.
Now that you can use the capabilities of DOS by writing your own DOS, see Escapes, quotation marks, and deltas in dynamic options syntax to learn about formatting rules in DOS.
For a comprehensive table of DOS formatters and selectors, see Selector and formatting functions.
Copy and paste the dashboard definition into your own dashboard to see the example:
{
"title": "Sparkline dynamic coloring based on trend example",
"description": "",
"inputs": {
"input_global_trp": {
"options": {
"defaultValue": "-24h@h,now",
"token": "global_time"
},
"title": "Global Time Range",
"type": "input.timerange"
}
},
"defaults": {
"dataSources": {
"ds.search": {
"options": {
"queryParameters": {
"earliest": "$global_time.earliest$",
"latest": "$global_time.latest$"
}
}
}
},
"visualizations": {
"global": {
"showProgressBar": true
}
}
},
"visualizations": {
"viz_JvmfYGrl": {
"containerOptions": {},
"context": {
"trendColorEditorConfig": [
{
"to": 0,
"value": "#9E2520"
},
{
"from": 0,
"value": "#1C6B2D"
}
]
},
"dataSources": {
"primary": "ds_yUVJ8eQR"
},
"options": {
"sparklineStrokeColor": "> trendColor",
"trendColor": "> trendValue | rangeValue(trendColorEditorConfig)"
},
"showLastUpdated": false,
"showProgressBar": true,
"type": "splunk.singlevalue"
}
},
"dataSources": {
"ds_yUVJ8eQR": {
"name": "Game purchases data",
"options": {
"query": "| makeresults count=50\n| streamstats count\n| eval _time = relative_time(now(), \"-\" . (50-count)*10 . \"m\")\n| eval throughput = 100 + (random() % 50) + (count * 1.5)\n| table _time throughput"
},
"type": "ds.search"
}
},
"layout": {
"globalInputs": [
"input_global_trp"
],
"layoutDefinitions": {
"layout_1": {
"options": {
"height": 960,
"width": 1440
},
"structure": [
{
"item": "viz_JvmfYGrl",
"position": {
"h": 310,
"w": 430,
"x": 1000,
"y": 30
},
"type": "block"
}
],
"type": "absolute"
}
},
"options": {},
"tabs": {
"items": [
{
"label": "Overview",
"layoutId": "layout_1"
}
]
}
}
}