Você está na página 1de 28

Create an app for the tutorial with a Simple

XML dashboard and extension


http://dev.splunk.com/view/webframework-tutorials/SP-CAAAERA

This first step covers the preliminary app setup by creating an app for the tutorial, a dashboard to
display the custom view, and a placeholder Simple XML extension that we'll modify later.

Note You need access to source files on your Splunk Enterprise instance, so you might need to
contact your Splunk administrator for permission and access.

1. On the Splunk Web home page, click the icon next to Apps.
2. Click Create app.
3. On the Add new page, fill out the properties of the new app:
o For Name, enter "Custom View Tutorial".
o For Folder name, enter "customviewtutorial".
o Under Template, select "barebones".
4. Click Save.

Next, add a Simple XML dashboard to the app:

1. On the Apps page, find the Custom View Tutorial app in the list and click Launch app.
(You can also open the app from the Splunk Web home page.)
2. On the navigation bar at the top of the page, click Dashboards.
3. Click Create New Dashboard, then fill out the dashboard properties:
o For Title, enter "Custom View".
o For Permissions, click Shared in App (this keeps the XML file in the app's
folder, $SPLUNK_HOME/etc/apps/customviewtutorial).
4. Click Create Dashboard.

The new Simple XML dashboard is displayed in edit mode.

5. Click Edit Source.


6. In the View box, replace the code with the following:

<dashboard script="customview.js">

<label>Custom View</label>

<row>
<html>
<div id="mycustomview"></div>
</html>

Page 1 of 28
</row>

</dashboard>

This dashboard has a simple HTML panel where we will display the custom view. The
script attribute in the dashboard tag refers to the customview.js extension file that
we'll create below.

7. Click Save, then click Done.

Finally, let's set up the app to use Simple XML extensions. We'll need to create a subfolder in the
app for static asset files and add a few JavaScript files.

1. Create an /appserver/static directory in your app under


$SPLUNK_HOME/etc/apps/customviewtutorial. You'll put all of your static assets in
this folder.
2. Create a placeholder for the Simple XML extension we'll use later.

In a text editor, paste the following code into a new file, then save it as customview.js
under $SPLUNK_HOME/etc/apps/customviewtutorial/appserver/static:

/* customview.js */

3. Create a placeholder for the custom JavaScript class we'll use later.

In a text editor, paste the following code into a new file, then save it as demoview.js
under $SPLUNK_HOME/etc/apps/customviewtutorial/appserver/static:

/* demoview.js */

4. Now that most of the required files and directory structure are in place, restart Splunk
Enterprise.

Page 2 of 28
Create a "hello, world!" view
This step shows how to create a basic view that displays "Hello, world!" in the HTML panel on the
dashboard and in the developer web console. To do this, we'll create a JavaScript class
called DemoView that inherits from the SimpleSplunkView base class.

Before we start, take a look at the SimpleSplunkView base class to get familiar with it—
simplesplunkview.js is located in:
$SPLUNK_HOME/share/splunk/search_mrsparkle/exposed/js/splunkjs/mvc/.

You'll see several public methods that you can override as needed:

 initialize: The constructor.


 formatData: Formats results data from Splunk and returns a handle to the data.
 formatResults: Same as formatData, except you can format the full set of data from the results model.
 displayMessage: Lets you render messages in a custom way.
 createView: Configures the custom vizualization and returns a handle to it.
 updateView: Puts Splunk data (returned by the formatData method) into the view (returned by
the createViewmethod) and renders it.
 clearView: Resets rendering.
 render: Creates the initial view and draws it on the screen. On subsequent calls, runs a full update
cycle by calling formatResults, formatData, then updateView.

The methods you'll typically need to override are formatData, createView, and updateView. All of the
public methods, properties, and events of this class are described in more detail in the Splunk Web
Framework Component Reference.

For this first simple example, we'll create a DemoView class that overrides the render method to display a
"Hello, world!" message. Then, we'll use the Simple XML extension customview.js placeholder we created
to instantiate the DemoViewclass in our Simple XML dashboard.

1. Create the DemoView class—open demoview.js, paste the following code into it, then save it:
/* demoview.js */

define(function(require, exports, module){

// Base class for custom views

var SimpleSplunkView = require('splunkjs/mvc/simplesplunkview');

// Define the custom view class

var DemoView = SimpleSplunkView.extend({

className: "demoview",

// Override the render function to make the view do something

Page 3 of 28
// In this example: print to the page and to the console

render: function() {

// Print to the page

this.$el.html("Hello, world!");

// Print to the console

console.log("Hello, world!");

return this;

});

return DemoView;

});

Here's what this code does:

 Loads the base class.


 Declares our new class, demoview, inheriting from the SimpleSplunkView base class.
 Overrides the render method to display a message on the page and in the console.

2. Instantiate the DemoView class in the Simple XML extension—open customview.js, paste the following
code into it, then save it:
/* customview.js */

require([

"/static/app/customviewtutorial/demoview.js",

"splunkjs/mvc/simplexml/ready!"

], function(DemoView) {

// Create a custom view

var customView = new DemoView({

id: "mycustomview",

Page 4 of 28
el: $("#mycustomview")

}).render();

});

Here's what this code does:

 Loads the required SplunkJS Stack libraries and components, plus the demoview library we just
created.
 Instantiates a customView instance of our DemoView class. The only requirement is a unique ID
value for the id property. The el property corresponds to the <div id="mycustomview"> tag
location on the dashboard.

Let's take a look at the dashboard.

1. Refresh Splunk Web to load the changes to the JavaScript files by opening
the http://<localhost:port>/debug/refreshURL in your web browser and clicking Refresh.

You'll need to do this each time you save changes to these JavaScript files.

2. Open the developer console for your browser.


3. Navigate to the dashboard, which should be http://<localhost:port>/app/customviewtutorial/custom_view.
You should see something like this:

Page 5 of 28
Pass values to the class constructor
Now we'll start adding elements to our very simple custom view. In this example, we'll show how you can
pass values to your view in different ways—when instantiating the view from the Simple XML extension
and by using the options dictionary (values to initialize the view).

1. Open customview.js and replace the code with the following, which contains a new "propA" property:
/* customview.js */

require([

"/static/app/customviewtutorial/demoview.js",

"splunkjs/mvc/simplexml/ready!"

], function(DemoView) {

// Create a custom view

var customView = new DemoView({

id: "mycustomview",

propA: "valA",
el: $("#mycustomview")
}).render();

});

2. Open demoview.js and replace the code with the following:


/* demoview.js */

define(function(require, exports, module){

// Base class for custom views

var SimpleSplunkView = require('splunkjs/mvc/simplesplunkview');

// Define the custom view class

var DemoView = SimpleSplunkView.extend({

className: "demoview",

Page 6 of 28
// Extend the options and provide initial values
options: {
propB: "valB"
},

// Override the render function to make the view do something


// In this example: print to the page and to the console
render: function() {

// Print the variables to the page


this.$el.html("propA: " + this.settings.get("propA") +
"<br>propB: " + this.settings.get("propB"));

// Print the variables to the console


console.log("propA is: ", this.settings.get("propA"));
console.log("propB is: ", this.settings.get("propB"));

return this;
}
});
return DemoView;
});

Here's what this code does:

 The options dictionary has been overridden with our "propB" property.
 The render method now displays the values of our two new properties, both on the page and in the
console.

3. Save your changes.


4. Refresh Splunk Web by opening the http://<localhost:port>/debug/refresh URL in your web browser and
clicking Refresh.
5. Navigate to the dashboard, http://<localhost:port>/app/customviewtutorial/custom_view. You should see
the two properties, propA and propB:

Page 7 of 28
Add a search to the view and display data from it
This step shows one of the main features of the SimpleSplunkView base class—built-in integration with
search managers. We'll add a search and redefine the custom view to display the results (a stats count
value) on the page. We'll also override the createView and updateView methods of the base class, which
you must override to work with a search:
 The createView method configures your view.
 The updateView method, which runs automatically whenever the search changes, takes the data from
your search and displays it in the view.

Let's add a search manager to the extension.

1. Open customview.js and replace the code with the following, which now includes a search manager. The
custom view instance also includes a managerid property, binding the view to the new search, just as
built-in views behave.
/* customview.js */

require([

"/static/app/customviewtutorial/demoview.js",

"splunkjs/mvc/searchmanager",
"splunkjs/mvc/simplexml/ready!"
], function(DemoView, SearchManager) {

// Create a custom view


var customView = new DemoView({
id: "mycustomview",
managerid: "mysearch",
el: $("#mycustomview")
}).render();

var mysearch = new SearchManager({


id: "mysearch",
preview: true,
cache: true,
search: "index=_internal | head 1000 | stats count"
});
});
2. Open demoview.js and replace the code with the following:
/* demoview.js */

define(function(require, exports, module){

// Base class for custom views

var SimpleSplunkView = require('splunkjs/mvc/simplesplunkview');

// Define the custom view class

Page 8 of 28
var DemoView = SimpleSplunkView.extend({

className: "demoview",

// Change the value of the "data" property


options: {
data: "results"
},

// Override this method to configure your view


// This function must return a handle to the view, which is then
passed
// to the updateView method as the first argument. Because there is
no
// visualization, just return 'this'
createView: function() {
return this;
},

// Override this method to put the Splunk data into the view
updateView: function(viz, data) {
// Print the data object to the console
console.log("The data object: ", data);

var myResults = data[0]; // Sets this to the first (and only)


row
this.$el.html("The count of search results: <b>" + myResults +
"</b>");
}
});

return DemoView;

});

Page 9 of 28
Here's what this code does:

 Sets the data property in the options section. (The default value is "preview".)
 Overrides the createView method to take advantage of the base class integration with our search.
This method only returns a handle to the view object. Because we aren't changing the data, we don't
add anything else to this method.
 Overrides the updateView method to display the results of the search. This method takes the results
of the search (the data argument) and displays it in our view (the viz argument). Our search returns a
single count, so retrieve the first row of data and display that on the page. The data object is printed
to the console for you to explore.
3. Save your changes.
4. Refresh Splunk Web by opening the http://<localhost:port>/debug/refresh URL in your web browser and
clicking Refresh.
5. Navigate to the dashboard, http://<localhost:port>/app/customviewtutorial/custom_view. You should see
the search results displayed on the page (and in the console):

Page 10 of 28
Format search data and display it
In this step we'll take the data from the search and format it before we send it to the view for display.

If you don't reformat the data, it is sent in the format as specified by the "output_mode" property, which
is "json" by default. However, our view expects a string. So, we'll override the formatData method to
change the format of the search results from an array to a string that contains an HTML list.
1. Let's change the search query to display more results. Open customview.js and replace the code with the
following code, which includes an updated search query:
/* customview.js */

require([

"/static/app/customviewtutorial/demoview.js",

"splunkjs/mvc/searchmanager",

"splunkjs/mvc/simplexml/ready!"

], function(DemoView, SearchManager) {

// Create a custom view

var customView = new DemoView({

id: "mycustomview",

managerid: "mysearch",

el: $("#mycustomview")

}).render();

var mysearch = new SearchManager({

id: "mysearch",

preview: true,

cache: true,

search: "index=_internal | head 1000 | stats count by sourcetype"


});

});

Page 11 of 28
2. Save this file, refresh Splunk Web, then view the dashboard to see the unformatted data. As you can see,
this is the data that is returned directly from splunkd in JSON format and is in need of some help:

3. Open demoview.js and replace the code with the following:


/* demoview.js */

define(function(require, exports, module){

// Base class for custom views

var SimpleSplunkView = require('splunkjs/mvc/simplesplunkview');

// Require Underscore.js to work with a list of search results


var _ = require("underscore");

// Define the custom view class


var DemoView = SimpleSplunkView.extend({
className: "demoview",

// Change the value of the "data" property


options: {
data: "results"
},

// Override this method to format your data in a specific way


// Our view expects HTML, so reformat the results array accordingly
formatData: function(data) {
// Display the data object to the console
console.log("The data object: ", data);
var mydatastring = "";

// Format each row of results as an HTML list


_.each(data, function(row, index){
mydatastring = mydatastring + "<li><b>" + row[0] + "</b>: "
+ row[1] + "</li>";
});

// Wrap the string with the unordered list tag


mydatastring = "<ul>" + mydatastring + "</ul>";
return mydatastring;
},

Page 12 of 28
// Override this method to configure your view
createView: function() {
return this;
},

// Override this method to put the Splunk data into the view
updateView: function(viz, data) {
// Display the reformatted data object to the console
console.log("HTML-formatted data: ", data);
this.$el.html("Count by sourcetype:" + data);
}
});

return DemoView;

});

The formatData method converts the data (an array) into a string (an HTML-formatted list), which is the
format the view expects. To work with lists, we also imported the Underscore library.

4. Save your changes.


5. Refresh Splunk Web by opening the http://<localhost:port>/debug/refresh URL in your web browser and
clicking Refresh.
6. Navigate to the dashboard, http://<localhost:port>/app/customviewtutorial/custom_view, to see the
formatted data

Page 13 of 28
Add a third-party visualization
Now that we've covered the basics, it's time for the real fun. In this example, we'll create a view that uses
a third-party visualization (a chart from Chart.js) to view our Splunk data.

We'll start by creating a Simple XML dashboard with an extension that implements a standard Splunk bar
chart. Then, we'll replace the Splunk chart with the third-party Chart.js visualization. Finally, we'll convert
that extension into a reusable custom view.

Before we start, you'll need to download a couple of things:

 We'll use sample music data from a static lookup table in CSV format: create a /lookups folder under
the customviewtutorial app folder, then download the musicdata.csv file
to$SPLUNK_HOME/etc/apps/customviewtutorial/lookups.
 Download the Chart.js library to $SPLUNK_HOME/etc/apps/customviewtutorial/appserver/static.
Note The version of Chart.js used for this tutorial is 1.0.2. Later versions of this library will not work.
 Restart Splunk Enterprise to update the customviewtutorial app with the new files.

Let's start by using an extension to create a Simple XML dashboard with a search manager, a text input,
and a chart.

1. Update the HTML panel in the Simple XML dashboard. In Splunk Web, navigate to your dashboard,
click Edit, and then click Source, then replace the Simple XML code with the following:
<dashboard script="customview.js">

<label>Custom View</label>

<row>

<html>

<h4>How many artists do you want to show? (1-21)</h4>


<div id="txtNum"></div>

<h2>Downloads per Artist</h2>


<div id="mychart"></div>
</html>
</row>

</dashboard>

Page 14 of 28
2. Update the extension to instantiate these SplunkJS Stack components. Open customview.js and replace
everything with the following code:
/* customview.js */

require([

"splunkjs/mvc",

"splunkjs/mvc/searchmanager",

"splunkjs/mvc/chartview",

"splunkjs/mvc/textinputview",

"splunkjs/mvc/simplexml/ready!"

], function(

// Keep these variables in the same order as the libraries above:

mvc,

SearchManager,

ChartView,

TextInputView

) {

// Create a text input for the number of artists to show

var myTextBox = new TextInputView({

id: "txtNum",

value: mvc.tokenSafe("$headNum$"),

default: "10",

el: $("#txtNum")

}).render();

// Downloads per artist

var mySearch = new SearchManager({

id: "mysearch",

preview: true,

Page 15 of 28
cache: true,

search: mvc.tokenSafe("| inputlookup musicdata.csv | search


bc_uri=/sync/addtolibrary* | stats count by artist_name | table artist_name,
count | head $headNum$"),

});

// Display the data in a Splunk chart

var myChart = new ChartView ({

id: "mychart",

managerid: "mysearch",

type: "bar",

el: $("#mychart")

}).render();

});

Here's what this code does:

 The SplunkJS Stack components are imported. The MVC library is required because we want to work
with tokens.
 A new search displays the number of downloads per artist from the musicdata.csv lookup. The
number of results (artists) to display is determined by the value in the text box. There are 21 artists in
this sample data set, so the UI provides a range.
 The text box input determines how many results to display, with a default of 10. This text box is
bound to the search using a token variable. Whenever this value changes, the search is run again.
 The Splunk chart is bound to the search.

3. Save your changes, refresh Splunk Web (http://<localhost:port>/debug/refresh), then navigate to the
dashboard (http://<localhost:port>/app/customviewtutorial/custom_view). Try entering different numbers
in the text box to change the search.

Page 16 of 28
Now we'll replace the Splunk chart with a radar chart from Chart.js, using the artist names for our chart
labels, and the download numbers as the chart data. Take a look at the Chart.js docs to get an idea of
how to implement this chart.

1. Update the HTML panel in the Simple XML dashboard to replace the Splunk chart div tag with a
tag for the radar chart. In Splunk Web, navigate to your dashboard, click Edit > Edit Source, then replace
the Simple XML code with the following:

<dashboard script="customview.js">

<label>Custom View</label>

<row>

<html>

<h4>How many artists do you want to show? (1-21)</h4>

<div id="txtNum"></div>

<h2>Downloads per Artist</h2>

<canvas id="mychart" width="700" height="700"></canvas>


</html>
</row>

</dashboard>
2. Open customview.js. Replace the code with the following:

Page 17 of 28
/* customview.js */

require([

"/static/app/customviewtutorial/chart.js",
"splunkjs/mvc",
"underscore",
"splunkjs/mvc/searchmanager",
"splunkjs/mvc/textinputview",
"splunkjs/mvc/simplexml/ready!"
], function(
// Keep these variables in the same order as the libraries above:
chart,
mvc,
_,
SearchManager,
TextInputView
) {

// Create a text input for the number of artists to show


var myTextBox = new TextInputView({
id: "txtNum",
value: mvc.tokenSafe("$headNum$"),
default: "10",
el: $("#txtNum")
}).render();

// Downloads per artist


var mySearch = new SearchManager({
id: "mysearch",
preview: true,
cache: true,
search: mvc.tokenSafe("| inputlookup musicdata.csv | search
bc_uri=/sync/addtolibrary* | stats count by artist_name | table artist_name,
count | head $headNum$")
});

// Get the result data


var myResults = mySearch.data("results");

// When data changes...


myResults.on("data", function() {
// This is the data object (a wrapper) that contains the results
console.log("Here is the data object: ", myResults.data());

// This is the Backbone collection with the same results


console.log("Here is the Backbone collection: ",
myResults.collection());
var chartLabels = [];
var chartData = [];
var maxDload = 0;

// Get the number of rows and the results


var numResults = myResults.data().rows.length; // Number of results
var artistData = myResults.data().rows; // The search results

Page 18 of 28
// Populate the chart (labels, data) with the search result data
_.each(artistData, function(artistDatum, i) {
// Use artist names as labels
chartLabels[i] = artistDatum[0];
// Use the number of downloads as the dataset
chartData[i] = parseInt(artistDatum[1])+1;
// Determine what the top download number is to set the chart
scale
if (chartData[i] > maxDload) {
maxDload = chartData[i];
}
});

// Set the radar chart data


var radarChartData = {
labels: chartLabels,
datasets: [
{
fillColor: "rgba(151,187,205,0.5)",
strokeColor: "rgba(151,187,205,1)",
pointColor: "rgba(151,187,205,1)",
pointStrokeColor: "#fff",
data: chartData
}
]
}

// Set radar chart options if different from the default


var radarOptions = {
scaleOverride: true,
scaleSteps: maxDload, // Set chart scale to top number of
downloads
scaleStepWidth: 1,
scaleStartValue: 0,
scaleShowLabels: true,
scaleShowLabelBackdrop: false,
}

// Create the radar chart


var myRadar = new
Chart(document.getElementById("mychart").getContext("2d")).Radar(radarChartDa
ta,radarOptions);

});

});

Here's what the code does:

 Loads the Chart.js library.


 Loads the Underscore library.
 Retrieves the results from the search. The example above shows how to access the results data
using both the Splunk Web Framework's data object and the Backbone's collection object (you can
use either one). If you're familiar with Backbone, you might prefer using the collection object to
access the raw data.

Page 19 of 28
 Iterates through the results to create an array of artist names for the chart labels, and an array of
download numbers for the chart data.
 Displays the chart using the chart labels and data from the search.

3. Save your changes, refresh Splunk Web (http://<localhost:port>/debug/refresh), then navigate to the
dashboard (http://<localhost:port>/app/customviewtutorial/custom_view):

So, this basic dashboard is acceptable as is. But what if we want to display the results from a different
search on the same page using another radar chart? Or maybe we want to display multiple radar charts
on a different dashboard in our app? We could add the JavaScript to multiple pages. But we could also
solve this problem by creating a custom view, which already includes methods to work with search data.

Let's take the JavaScript from this extension and place it into our DemoView class.

4. Open demoview.js and replace the code with the following:


/* demoview.js */

define(function(require, exports, module){

// Base class for custom views

var SimpleSplunkView = require('splunkjs/mvc/simplesplunkview');

Page 20 of 28
// Require Underscore.js to work with search results

var _ = require("underscore");

// Require the Chart.js library for the radar chart

var chart = require("/static/app/customviewtutorial/chart.js");

// Define the custom view class

var DemoView = SimpleSplunkView.extend({

className: "demoview",

// Define our initial values, set the type of results to return

options: {

maxDload: 0, // Chart scale

mychartid: "", // ID for the chart

data: "results" // Results type

},

// Override this method to configure the view

createView: function() {

// Create a unique chart ID based on the view's unique ID

mychartid = this.name + "-radar";

this.$el.html('<canvas id="' + mychartid + '" width="700"


height="700"></canvas>');

return this;

},

// Override this method to format the data for the radar chart

Page 21 of 28
formatData: function(data) {

// The data object contains the search results

var chartLabels=[];

var chartData=[];

maxDload = 0;

// Populate the chart (labels, data) with the search result data

_.each(data, function(row, i){

chartLabels[i] = row[0];

chartData[i] = parseInt(row[1]) + 1;

// Determine what the top download number is to set the chart


scale

if (chartData[i] > maxDload) {

maxDload = chartData[i];

});

// Set the radar chart data

var radarChartData = {

labels: chartLabels,

datasets: [

fillColor: "rgba(151,187,205,0.5)",

strokeColor: "rgba(151,187,205,1)",

pointColor: "rgba(151,187,205,1)",

pointStrokeColor: "#fff",

data: chartData

Page 22 of 28
]

return radarChartData;

},

// Override this method to put the Splunk data into the view

updateView: function(viz, radarData) {

// Set radar chart options

var radarOptions = {

scaleOverride: true,

scaleSteps: maxDload,

scaleStepWidth: 1,

scaleStartValue: 0,

scaleShowLabels: true,

scaleShowLabelBackdrop: false,

// Create the radar chart

var myRadar = new


Chart(document.getElementById(mychartid).getContext("2d")).Radar(radarData,
radarOptions);

});

return DemoView;

});

Page 23 of 28
The code does the same things it did in the customview.js extension—it loads the Chart.js library, takes
the data from the search and formats it for the radar chart, and then displays the chart. But in this format,
we break out the steps over the options dictionary and methods we want to override
in SimpleSplunkView:

 options: Defines initial variables.


 createView: Defines how the view is displayed using the <canvas> tag. This also creates a unique
chart ID because we can't use a hard-coded "mychart" ID, especially if we want to be able to place
multiple views on a page.
 formatData: Takes the results, then extracts the artist names for chart labels and the number of
downloads for chart data. Some of the code is simpler here because this method provides more
direct access to the search data model.
 updateView: Sets the chart properties, then displays the radar chart in the view, using the data that is
passed in from formatData and the view that is passed in from createView.

5. Now that the JavaScript code has been relocated, we need to add the div tag for the view back to the
dashboard. In Splunk Web, navigate to your dashboard, click Edit > Edit Source, then replace the Simple
XML code with the following:
<dashboard script="customview.js">

<label>Custom View</label>

<row>

<html>

<h4>How many artists do you want to show? (1-21)</h4>

<div id="txtNum"></div>

<h2>Downloads per Artist</h2>

<div id="mycustomview"></div>
</html>
</row>

</dashboard>
6. And, we need to instantiate the DemoView class again in the extension. Open customview.js and
replace the code with the following:
/* customview.js */

require([

"splunkjs/mvc",

"/static/app/customviewtutorial/demoview.js",
"splunkjs/mvc/searchmanager",

Page 24 of 28
"splunkjs/mvc/textinputview",
"splunkjs/mvc/simplexml/ready!"
], function(
// Keep these variables in the same order as the libraries above:
mvc,
DemoView,
SearchManager,
TextInputView
) {

// Create a text input for the number of artists to show


var myTextBox = new TextInputView({
id: "txtNum",
value: mvc.tokenSafe("$headNum$"),
default: "10",
el: $("#txtNum")
}).render();

// Downloads per artist


var mySearch = new SearchManager({
id: "mysearch",
preview: true,
cache: true,
search: mvc.tokenSafe("| inputlookup musicdata.csv | search
bc_uri=/sync/addtolibrary* | stats count by artist_name | table artist_name,
count | head $headNum$")
});

// Custom view
var customView = new DemoView({
id: "mycustomview",
managerid: "mysearch",
el: $("#mycustomview")
}).render();

});

7. Save these changes, refresh Splunk Web (http://<localhost:port>/debug/refresh), then navigate to


the dashboard (http://<localhost:port>/app/customviewtutorial/custom_view). It should look exactly the
same as it did previously:

Page 25 of 28
But let's show how useful the reusable custom view is by adding another chart to the same dashboard to
display a different search.

8. Add another div tag to the dashboard for the additional view. In Splunk Web, navigate to your
dashboard, click Edit > Edit Source, then replace the Simple XML code with the following:

<dashboard script="customview.js">

<label>Custom View</label>

<row>

<html>

<h4>How many artists do you want to show? (1-21)</h4>

<div id="txtNum"></div>

<h2>Downloads per Artist</h2>

<div id="mycustomview1"></div>

<h2>Searches on Artist</h2>
<div id="mycustomview2"></div>
</html>
</row>

</dashboard>
9. Let's add another search to the extension, and instantiate another custom radar chart view.
Open customview.js and replace everything with the following code:
/* customview.js */

require([

"splunkjs/mvc",

"/static/app/customviewtutorial/demoview.js",

"splunkjs/mvc/searchmanager",

"splunkjs/mvc/textinputview",

"splunkjs/mvc/simplexml/ready!"

], function(

// Keep these variables in the same order as the libraries above:

Page 26 of 28
mvc,

DemoView,

SearchManager,

TextInputView

) {

// Create a text input for the number of artists to show

var myTextBox = new TextInputView({

id: "txtNum",

value: mvc.tokenSafe("$headNum$"),

default: "10",

el: $("#txtNum")

}).render();

// Set up the search managers

// Downloads per artist


var mySearch1 = new SearchManager({
id: "mysearch1",
preview: true,
cache: true,
search: mvc.tokenSafe("| inputlookup musicdata.csv | search
bc_uri=/sync/addtolibrary* | stats count by artist_name | table artist_name,
count | head $headNum$")
});

// Searches on artist
var mySearch2 = new SearchManager({
id: "mysearch2",
cache: true,
search: mvc.tokenSafe("| inputlookup musicdata.csv | search
bc_uri=/browse/search* | stats count by search_terms | table search_terms,
count | head $headNum$")
});

// Create the custom views for each search

// Custom view showing search1


var customView1 = new DemoView({
id: "mycustomview1",

Page 27 of 28
managerid: "mysearch1",
el: $("#mycustomview1")
}).render();

// Custom view showing search2


var customView2 = new DemoView({
id: "mycustomview2",
managerid: "mysearch2",
el: $("#mycustomview2")
}).render();

});

In this example, we've added another custom view and search manager, and updated the IDs with a "1"
and "2" to keep things tidy. The new search lists the number of searches per artist keyword, and since the
results have the same format as the original search (a list of strings and numbers), we don't need to do
anything to the way the data is formatted. This other search also is bound to the same text box that sets
the number of results to return.

10. Save these changes, refresh Splunk Web (http://<localhost:port>/debug/refresh), then navigate to
the dashboard (http://<localhost:port>/app/customviewtutorial/custom_view) to see both radar charts:

Page 28 of 28