Sankey diagrams
Use Sankey diagrams to visualize node entities and the proportional flow between them. The width of the links represent the volume of flow.
Generate a Sankey diagram
- Select the Add chart button (
) in the editing toolbar and browse through the available charts. Choose the Sankey diagram.
- Select the diagram on your dashboard to highlight it with the blue editing outline.
- Set up a new data source by selecting + Create search and adding a search to the SPL query window. Or, you can select an existing data source under the Search, Saved search, or Chain search sections.
- (Optional) You can also write a new ID that describes the search better than the default by changing the ID in Data source name.
- Select Apply and close.
Configuration panel options
You can use the Configuration panel to configure the following Sankey diagram components.
Title
Give your visualization a name. This is also helpful when searching for individual visualizations in the dashboard definitions. This name is not the same as the automatically assigned unique ID.
Description
Give your visualization a description to explain what the user is viewing.
Data sources
You can choose one of the following data options:
- An existing data source or create a new data source
- A chain search
- A saved search
Your data source must have the following in the fields stanza:
source- the node entity from which flow beginstarget- the node entity to which flow endsvalue- a numerical value that represents the width of the source node
You can also add an optional field for dynamic coloring. For example, if you add another value and name it value2.
Data Selection
Use the Link Value Field to specify the data source field that determines link width.
Color and style
-
Title color: configure a font color for the visualization title.
-
Description color: configure a font color for the visualization description.
- Color mode:
- Categorical uses a unique color for each source node.
- Dynamic provides the ability to assign colors based on values returned from a selected field. Under Link, select the color range to open the Dynamic coloring: link dialog. You can configure one of the following:
Color by Ranges to assign colors based on numeric ranges (e.g., values less than 25 are red, between 25 and 50 are orange, between 50 and 75 are yellow, and 75 or higher are green).
Color by Matches to assign colors to specific values.
Use the asterisk (*) character as a wildcard in match values to represent any number of characters in a string. You can place an asterisk anywhere within the string. Matching prioritizes exact values, followed by values with more common characters. If multiple match values share the same length and number of wildcards, they will be matched according to their order of entry. For example, you can configure 2* as a match value to match 2, 20, 200, and so on.
- Background color: to change the background color of the diagram panel, click the color box to select from a palette or enter a hexadecimal code. For example, enter #FF7189 for a shade of pink.
Code
Select your visualization or its search to view and edit the source code in real-time. You can also change the Visualization ID to a more readable ID to help identify this visualization in the source code.
Sankey diagram example
The following example shows a dashboard with a Sankey diagram titled "Intern Recruitment to Full-time Conversion Flow", which provides data for an intern recruitment process, tracking the flow from initial application to becoming a full-time employee. The dashboard also includes a table which shows the same data as the Sankey diagram for reference.
Source code
The following provides the source code for the data source that powers the example Sankey diagram and table. To power a Sankey diagram, a data source must return results with the following field names:
source: node entity from which the flow beginstarget: node entity where the flow endsvalue: numerical value that represents the width of the source node
| makeresults
| eval total_applicants=100
| eval interviewed=round(total_applicants * 0.60)
| eval offer_extended=round(interviewed * 0.75)
| eval internship_started=round(offer_extended * 0.90)
| eval full_time_converted=round(internship_started * 0.85)
| eval flow_data = mvappend(
"Applied->Interviewed," . interviewed,
"Applied->Rejected/Did Not Proceed," . (total_applicants - interviewed),
"Interviewed->Offer Extended," . offer_extended,
"Interviewed->Rejected/Did Not Proceed," . (interviewed - offer_extended),
"Offer Extended->Internship Started," . internship_started,
"Offer Extended->Rejected/Did Not Proceed," . (offer_extended - internship_started),
"Internship Started->Full-time Employee," . full_time_converted,
"Internship Started->Rejected/Did Not Proceed," . (internship_started - full_time_converted)
)
| mvexpand flow_data
| rex field=flow_data "(?<source>[^->]+)->(?<target>[^,]+),(?<value>\d+)"
| fields source, target, value
| eval value=tonumber(value)
| where value > 0
The following provides a breakdown of each line in the sample code:
The first 6 lines (from
| makeresultsto| eval full_time_converted=round(internship_started * 0.85)create the example recruitment data by defining the number of total applicants and what percentage of applicants at each stage move on to the next. For example, the number of total applications is 100, while 60% of applicants moved on to the interview round, as| eval interviewed=round(total_applicants * 0.60)defines.| eval flow_data = mvappend(...)constructs the core data for the Sankey diagram. It creates a multivalue field, flow_data, with each entry in flow_data providing data for 1 link in the Sankey diagram in the format "SourceNode->TargetNode,". <value>. The value for the entry may be the value of a field or the difference between 2 fields.For example, for Applied->Interviewed, which is the link for applicants who moved on to the interview stage after applying, the value is simply the value of the interviewed field, which was defined as
| eval interviewed=round(total_applicants * 0.60).For Applied->Rejected/Did Not Proceed, which is the link for applicants who did not move on to the interview stage after applying, the value is the number of total applicants minus the number of those who moved onto the interview round
(total_applicants - interviewed).
| mvexpand flow_dataexpands the flow_data field into separate events so that each flow is a distinct row in the results.| rex field=flow_data "(?<source>[^->]+)->(?<target>[^,]+),(?<value>\d+)"uses regular expressions to extract the source node, target node, and value information from each flow_data entry, using the source, target, and value field names that Sankey diagrams require.| fields source, target, valuekeeps only the fields necessary to build the Sankey diagram: source, target, and value.| eval value=tonumber(value)ensures that the value field is treated as a numerical type, which is required for the Sankey diagram to size links correctly.| where value > 0removes flows that have a value not greater than 0 to prevent unnecessary nodes or links.
{
"title": "Sankey 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_FOgBv9oe": {
"containerOptions": {},
"dataSources": {
"primary": "ds_6IxLUIWS"
},
"showLastUpdated": false,
"showProgressBar": true,
"title": "Intern Recruitment to Full-time Conversion Flow",
"type": "splunk.sankey"
},
"viz_KybkfUHS": {
"dataSources": {
"primary": "ds_6IxLUIWS"
},
"title": "Intern Recruitment to Full-time Conversion Flow (Table)",
"type": "splunk.table"
}
},
"dataSources": {
"ds_6IxLUIWS": {
"name": "Sankey",
"options": {
"query": "| makeresults\n| eval total_applicants=100\n| eval interviewed=round(total_applicants * 0.60)\n| eval offer_extended=round(interviewed * 0.75)\n| eval internship_started=round(offer_extended * 0.90)\n| eval full_time_converted=round(internship_started * 0.85)\n| eval flow_data = mvappend(\n \"Applied->Interviewed,\" . interviewed,\n \"Applied->Rejected/Did Not Proceed,\" . (total_applicants - interviewed),\n \"Interviewed->Offer Extended,\" . offer_extended,\n \"Interviewed->Rejected/Did Not Proceed,\" . (interviewed - offer_extended),\n \"Offer Extended->Internship Started,\" . internship_started,\n \"Offer Extended->Rejected/Did Not Proceed,\" . (offer_extended - internship_started),\n \"Internship Started->Full-time Employee,\" . full_time_converted,\n \"Internship Started->Rejected/Did Not Proceed,\" . (internship_started - full_time_converted)\n)\n| mvexpand flow_data\n| rex field=flow_data \"(?<source>[^->]+)->(?<target>[^,]+),(?<value>\\d+)\"\n| fields source, target, value\n| eval value=tonumber(value)\n| where value > 0"
},
"type": "ds.search"
}
},
"layout": {
"globalInputs": [
"input_global_trp"
],
"layoutDefinitions": {
"layout_1": {
"options": {
"height": 960,
"width": 1440
},
"structure": [
{
"item": "viz_FOgBv9oe",
"position": {
"h": 400,
"w": 1440,
"x": 0,
"y": 0
},
"type": "block"
},
{
"item": "viz_KybkfUHS",
"position": {
"h": 400,
"w": 1440,
"x": 0,
"y": 400
},
"type": "block"
}
],
"type": "grid"
}
},
"options": {},
"tabs": {
"items": [
{
"label": "Overview",
"layoutId": "layout_1"
}
]
}
}
} Source options for Sankey diagrams
| Property | Type | Default | Description |
|---|---|---|---|
| backgroundColor | string | > themes.defaultBackgroundColor | Specify the color for the background. You may use a dataSource to apply the color. The default for enterprise light is "#ffffff". The default for enterprise dark is "#000000". The default for prisma dark is "#0b0c0e". |
| colorMode | (categorical | dynamic) | categorical | Specify the coloring method used for the links. When set to "categorical" the nodes and links will be colored based on the "seriesColors". When set to "dynamic" the links will be colored based on the dynamic string assigned to "linkColors". ("categorical" | "dynamic") |
| linkOpacity | number | 0.5 | Specify the opacity of the links. Choose a number in the range of 0 - 1 (inclusive). |
| linkValues | string | > primary | seriesByType('number') | Specify the dataSource to apply link width. |
| linkColors | string | > linkValues | rangeValue(linkColorRangeConfig) | Specify the coloring method used for the links when the colorMode "dynamic" is specified. |
| resultLimit | number | 1000 | Specify the maximum length of link data points rendered. |
| seriesColors | string | #7B56DB,#009CEB,#00CDAF,#DD9900,#FF677B,#CB2196,#813193,#0051B5,#008C80,#99B100,#FFA476,#FF6ACE,#AE8CFF,#00689D,#00490A,#465D00,#9D6300,#F6540B,#FF969E,#E47BFE | Specify the colors used for a series. For example, ["#FF0000", "#0000FF", "#008000"]. |