Dashboards & Visualizations

Example Of Chart Overlay ?

john_loch
Explorer

Hi Folks,

I'm trying to find an example of a view with chart overlays. Basically I want to take a chart with Y axis on Left, then a Y axis on right, and overlay the two..

The docs suggest this exact scenario but fall short of an actual example.

Can anyone provide an example of the XML you would use to do this please ?

Thanks in advance 🙂

Tags (3)
1 Solution

bbingham
Builder

Here's another example that's very similar to the one above:

    <module name="HiddenSavedSearch" layoutPanel="panel_row5_col1" group="Rolling Claim Data" autoRun="True">
            <param name="savedSearch">HTAnalytics_RollingDelta_Data</param>
            <module name="HiddenChartFormatter">
                    <param name="charting.chart">column</param>
                    <param name="charting.chart.columnAlignment">.5</param>
                    <param name="charting.axisX">time</param>
                    <param name="charting.axisLabelsX.majorUnit">P1M</param>
                    <param name="charting.axisLabelsX.minorUnit">P1M</param>
                    <param name="charting.axisY">numeric</param>
                    <param name="charting.axisY.minimumNumber">-80</param>
                    <param name="charting.axisY.maximumNumber">80</param>
                    <param name="charting.axisTitleX.text">Month of Year</param>
                    <param name="charting.axisTitleY.text">Percent Increase/Decrease</param>
                    <param name="charting.axisY2">numeric</param>
                    <param name="charting.axisY2.minimumNumber">-80</param>
                    <param name="charting.axisY2.maximumNumber">80</param>
                    <param name="charting.axisLabelsY2">#axisLabelsY</param>
                    <param name="charting.axisLabelsY2.axis">@axisY2</param>
                    <param name="charting.axisLabelsY2.placement">right</param>
                    <param name="charting.data0">results</param>
                    <param name="charting.data0.jobID">@data.jobID</param>
                    <param name="charting.data1">view</param>
                    <param name="charting.data1.table">@data0</param>
                    <param name="charting.data1.columns">[0,1]</param>
                    <param name="charting.data2">view</param>
                    <param name="charting.data2.table">@data0</param>
                    <param name="charting.data2.columns">[0,2]</param>
                    <param name="charting.chart.data">@data1</param>
                    <param name="charting.chart2">line</param>
                    <param name="charting.chart2.axisY">@axisY2</param>
                    <param name="charting.chart2.data">@data2</param>
                    <param name="charting.layout.charts">[@chart,@chart2]</param>
                    <param name="charting.layout.axisTitles">[@axisTitleX,@axisTitleY,@axisTitleY2]</param>
                    <module name="FlashChart">
                            <param name="height">600px</param>
                    </module>
            </module>
    </module>

This module creates a 2 separate types of graphs and places them on top one another based on 1 input series. The first chart builds a column chart based on the 1 "column" of the series and the second chart builds a line chart based on the second series. Basically a table like this:

Month_Of_Year      ColumnChart(incrase/decrease)         LineChart(rolling average)
Jan                           %10                                  .5%
Feb                           %15                                  .5%
Mar                           %20                                   5%
Apr                           %05                                  10%
May                          -%10                                  -1%
Jun                           %50                                  .5%
Jly                           %20                                  .5%
Aug                          -%20                                  .5%
Sep                          -%50                                  .5%

etc, and here's the sample chart: SampleChart

Here's how it works:

Create a base module using a saved search for my data:

    <module name="HiddenSavedSearch" layoutPanel="panel_row5_col1" group="Rolling Claim Data" autoRun="True">
            <param name="savedSearch">HTAnalytics_RollingDelta_Data</param>

Next, take the results from that search and format a chart, in this case, the first chart, our column chart:

            <module name="HiddenChartFormatter">
                    <param name="charting.chart">column</param>
                    <param name="charting.chart.columnAlignment">.5</param>
                    <param name="charting.axisX">time</param>
                    <param name="charting.axisLabelsX.majorUnit">P1M</param>
                    <param name="charting.axisLabelsX.minorUnit">P1M</param>
                    <param name="charting.axisY">numeric</param>
                    <param name="charting.axisY.minimumNumber">-80</param>
                    <param name="charting.axisY.maximumNumber">80</param>
                    <param name="charting.axisTitleX.text">Month of Year</param>
                    <param name="charting.axisTitleY.text">Percent Increase/Decrease</param>

Now lets adjust the some base settings for our second (line) chart's axis's:

                    <param name="charting.axisY2">numeric</param>
                    <param name="charting.axisY2.minimumNumber">-80</param>
                    <param name="charting.axisY2.maximumNumber">80</param>
                    <param name="charting.axisLabelsY2">#axisLabelsY</param>
                    <param name="charting.axisLabelsY2.axis">@axisY2</param>
                    <param name="charting.axisLabelsY2.placement">right</param>

Now we need to tell splunk how to get the data for each chart:

                    <param name="charting.data0">results</param>
                    <param name="charting.data0.jobID">@data.jobID</param>

The 2 lines above tell splunk to use the base data from the saved search and send it to a new definition data0

After Data0's defined, we're going to establish which columns are used for what chart:

                    <param name="charting.data1">view</param>
                    <param name="charting.data1.table">@data0</param>
                    <param name="charting.data1.columns">[0,1]</param>

The above tells splunk to create another definition "data1", pull the results from data0, but only to pull first column for the xaxis (time) and then only the 1 column of data in the series.

Now do the same thing for our line chart, but tell splunk to use the 2nd column in the series for the line:

                    <param name="charting.data2">view</param>
                    <param name="charting.data2.table">@data0</param>
                    <param name="charting.data2.columns">[0,2]</param>

Now establish the column chart to use our new data source for it's input:

                    <param name="charting.chart.data">@data1</param>

I then tell the 2nd chart to be a line chart, and I give it a hidden axis incase I ever want to change the scale of my line graph (defined earlier with axisY2):

                    <param name="charting.chart2">line</param>
                    <param name="charting.chart2.axisY">@axisY2</param>

Lastly I set the input mode for the 2nd chart:

                    <param name="charting.chart2.data">@data2</param>

Then tell the layout portion of the charting module to draw2 charts:

                    <param name="charting.layout.charts">[@chart,@chart2]</param>

And then to build my custom axis:

                    <param name="charting.layout.axisTitles">[@axisTitleX,@axisTitleY,@axisTitleY2]</param>

And lastly, draw the graph:

                    <module name="FlashChart">
                            <param name="height">600px</param>
                    </module>
            </module>
    </module>

Hope this helps!

View solution in original post

phoenixdigital
Builder

Ok I thought I would give this a try in flash to see how they printed before I dug too deep into d3js charts.

I have constructed searches in this example that will work without my data so anyone can try these examples.

So I have this advancedXML and it works however see next section where I am having issues.

    <view autoCancelInterval="90" isVisible="true" objectMode="SimpleDashboard" onunloadCancelJobs="true" refresh="-1" template="dashboard.html">
    <label>MultiChartTypes</label>
    <module name="AccountBar" layoutPanel="appHeader"/>
    <module name="AppBar" layoutPanel="navigationHeader"/>
    <module name="Message" layoutPanel="messaging">
        <param name="maxSize">1</param>
        <param name="filter">*</param>
        <param name="clearOnJobDispatch">False</param>
    </module>
    <module name="DashboardTitleBar" layoutPanel="viewHeader"/>
    <module name="Message" layoutPanel="navigationHeader">
        <param name="maxSize">1</param>
        <param name="filter">splunk.search.job</param>
        <param name="level">warn</param>
        <param name="clearOnJobDispatch">True</param>
    </module>
    <module name="HiddenSearch" layoutPanel="panel_row1_col1" autoRun="True">
        <param name="search">| gentimes start=01/01/2013  | eval field1 = random() % 100 | eval field2 = random() % 150 | eval date_month = strftime(starttime, "%b") | dedup date_month | fields date_month field1 field2</param>
        <param name="latest">+6m</param>
        <param name="earliest">0</param>

        <module name="HiddenChartFormatter">

            <param name="charting.data0">results</param>
            <param name="charting.data0.jobID">@data.jobID</param>

            <param name="charting.data1">view</param>
            <param name="charting.data1.table">@data0</param>
            <param name="charting.data1.columns">[0,1]</param>

            <param name="charting.data2">view</param>
            <param name="charting.data2.table">@data0</param>
            <param name="charting.data2.columns">[0,2]</param>

            <param name="charting.chart">column</param>
            <param name="charting.chart.data">@data1</param>

            <param name="charting.chart2">line</param>
            <param name="charting.chart2.data">@data2</param>

            <param name="charting.layout.charts">[@chart,@chart2]</param>
            <module name="FlashChart">
                <module name="Gimp"/>
            </module>
            <module name="ViewRedirectorLink">
                <param name="viewTarget">flashtimeline</param>
            </module>
        </module>
    </module>
</view>

Now however I have a primary base search and I fire off many sub searches(PostProcesses) from this and this is where the chart fails.

    <view autoCancelInterval="90" isVisible="true" objectMode="SimpleDashboard" onunloadCancelJobs="true" refresh="-1" template="dashboard.html">
    <label>MultiChartTypes</label>
    <module name="AccountBar" layoutPanel="appHeader"/>
    <module name="AppBar" layoutPanel="navigationHeader"/>
    <module name="Message" layoutPanel="messaging">
        <param name="maxSize">1</param>
        <param name="filter">*</param>
        <param name="clearOnJobDispatch">False</param>
    </module>
    <module name="DashboardTitleBar" layoutPanel="viewHeader"/>
    <module name="Message" layoutPanel="navigationHeader">
        <param name="maxSize">1</param>
        <param name="filter">splunk.search.job</param>
        <param name="level">warn</param>
        <param name="clearOnJobDispatch">True</param>
    </module>
    <module name="HiddenSearch" layoutPanel="panel_row1_col1" autoRun="True">
        <param name="search">| gentimes start=01/01/2013  | eval field1 = random() % 100 | eval field2 = random() % 150 | eval date_month = strftime(starttime, "%b")</param>
        <param name="latest">+6m</param>
        <param name="earliest">0</param>

        <module name="HiddenPostProcess" autoRun="True">
            <param name="search">dedup date_month | fields date_month field1 field2</param>
            <module name="HiddenChartFormatter">

                <param name="charting.data0">results</param>
                <param name="charting.data0.jobID">@data.jobID</param>

                <param name="charting.data1">view</param>
                <param name="charting.data1.table">@data0</param>
                <param name="charting.data1.columns">[0,1]</param>

                <param name="charting.data2">view</param>
                <param name="charting.data2.table">@data0</param>
                <param name="charting.data2.columns">[0,2]</param>

                <param name="charting.chart">column</param>
                <param name="charting.chart.data">@data1</param>

                <param name="charting.chart2">line</param>
                <param name="charting.chart2.data">@data2</param>

                <param name="charting.layout.charts">[@chart,@chart2]</param>
                <module name="FlashChart">
                    <module name="Gimp"/>
                </module>
                <module name="ViewRedirectorLink">
                    <param name="viewTarget">flashtimeline</param>
                </module>
            </module>
        </module>
    </module>
</view>

I am sure its something to do with this line which is using the base search. How do I use the postProcess search results?

<param name="charting.data0">results</param>

Also are there any more resources for d3js charts apart from this?
http://dev.splunk.com/view/SP-CAAAEN6

0 Karma

norbert_hamel
Communicator

I have not yet combined overlay charts with post-processing, but just a few hints:
Have you tested this post-processing with a standard chart without overlay technique? From a gutt feeling I would say that the base search is not defined properly to fill the post-processing search.
I have worked a bit with the post-processing in sideview, and from this brilliant documentation I learned how to use post-processing. From my understanding you need a reporting command like stats in your base search and list the fields, which you want to use in the post-processing search later on.

0 Karma

phoenixdigital
Builder

Ahhhh flash only. That will be what the issue is.

Thanks for the heads up.

I might have to look into d3js charts.

0 Karma

norbert_hamel
Communicator

Hi phoenixdigital,

yes this is running in Splunk 6 as well.
And the great part of the story is that this will also work without Advanced XML.
I have heavily used overlay charts in Advanced XML over the last 2 years, and the major drawback (besides the somehow complex configuration) is the fact that this works with Flash only. hich is a real drawback in our case.
With Splunk 6 you can use d3js charts for that, and its really working. I have started during .conf2013 with that, so some elements needs to be checked, but in general it work.
If you would like to post some details here I will try to help.

Cheers
Norbert

0 Karma

phoenixdigital
Builder

Does this work in Splunk 6.0?

I cant seem to get an almost identical example to work.

0 Karma

HattrickNZ_2
Engager

How or where are you playing around with the charting.axisLabelsY2.* values?? is this in the XML of a dashboard or somewhere else?

0 Karma

bbingham
Builder

I posted a response to your question in the thread you started, let me know if you have any issues!

0 Karma

herbie
Path Finder

Hi Guys, This thread was really helpful, I'm trying to do the same thing. I'm trying to graph HTTP Hits vs Response Times in an overlayed chart.

The only problem I'm having is that the Yaxis 2 doesn't show up on the right, and I noticed it doesn't show in the picture above either. I've been playing around with the charting.axisLabelsY2.* values but can't seem to get it to appear.

Do you know if there's any way to get the second Y axis to show?

Thanks Ashley

0 Karma

bbingham
Builder

Here's another example that's very similar to the one above:

    <module name="HiddenSavedSearch" layoutPanel="panel_row5_col1" group="Rolling Claim Data" autoRun="True">
            <param name="savedSearch">HTAnalytics_RollingDelta_Data</param>
            <module name="HiddenChartFormatter">
                    <param name="charting.chart">column</param>
                    <param name="charting.chart.columnAlignment">.5</param>
                    <param name="charting.axisX">time</param>
                    <param name="charting.axisLabelsX.majorUnit">P1M</param>
                    <param name="charting.axisLabelsX.minorUnit">P1M</param>
                    <param name="charting.axisY">numeric</param>
                    <param name="charting.axisY.minimumNumber">-80</param>
                    <param name="charting.axisY.maximumNumber">80</param>
                    <param name="charting.axisTitleX.text">Month of Year</param>
                    <param name="charting.axisTitleY.text">Percent Increase/Decrease</param>
                    <param name="charting.axisY2">numeric</param>
                    <param name="charting.axisY2.minimumNumber">-80</param>
                    <param name="charting.axisY2.maximumNumber">80</param>
                    <param name="charting.axisLabelsY2">#axisLabelsY</param>
                    <param name="charting.axisLabelsY2.axis">@axisY2</param>
                    <param name="charting.axisLabelsY2.placement">right</param>
                    <param name="charting.data0">results</param>
                    <param name="charting.data0.jobID">@data.jobID</param>
                    <param name="charting.data1">view</param>
                    <param name="charting.data1.table">@data0</param>
                    <param name="charting.data1.columns">[0,1]</param>
                    <param name="charting.data2">view</param>
                    <param name="charting.data2.table">@data0</param>
                    <param name="charting.data2.columns">[0,2]</param>
                    <param name="charting.chart.data">@data1</param>
                    <param name="charting.chart2">line</param>
                    <param name="charting.chart2.axisY">@axisY2</param>
                    <param name="charting.chart2.data">@data2</param>
                    <param name="charting.layout.charts">[@chart,@chart2]</param>
                    <param name="charting.layout.axisTitles">[@axisTitleX,@axisTitleY,@axisTitleY2]</param>
                    <module name="FlashChart">
                            <param name="height">600px</param>
                    </module>
            </module>
    </module>

This module creates a 2 separate types of graphs and places them on top one another based on 1 input series. The first chart builds a column chart based on the 1 "column" of the series and the second chart builds a line chart based on the second series. Basically a table like this:

Month_Of_Year      ColumnChart(incrase/decrease)         LineChart(rolling average)
Jan                           %10                                  .5%
Feb                           %15                                  .5%
Mar                           %20                                   5%
Apr                           %05                                  10%
May                          -%10                                  -1%
Jun                           %50                                  .5%
Jly                           %20                                  .5%
Aug                          -%20                                  .5%
Sep                          -%50                                  .5%

etc, and here's the sample chart: SampleChart

Here's how it works:

Create a base module using a saved search for my data:

    <module name="HiddenSavedSearch" layoutPanel="panel_row5_col1" group="Rolling Claim Data" autoRun="True">
            <param name="savedSearch">HTAnalytics_RollingDelta_Data</param>

Next, take the results from that search and format a chart, in this case, the first chart, our column chart:

            <module name="HiddenChartFormatter">
                    <param name="charting.chart">column</param>
                    <param name="charting.chart.columnAlignment">.5</param>
                    <param name="charting.axisX">time</param>
                    <param name="charting.axisLabelsX.majorUnit">P1M</param>
                    <param name="charting.axisLabelsX.minorUnit">P1M</param>
                    <param name="charting.axisY">numeric</param>
                    <param name="charting.axisY.minimumNumber">-80</param>
                    <param name="charting.axisY.maximumNumber">80</param>
                    <param name="charting.axisTitleX.text">Month of Year</param>
                    <param name="charting.axisTitleY.text">Percent Increase/Decrease</param>

Now lets adjust the some base settings for our second (line) chart's axis's:

                    <param name="charting.axisY2">numeric</param>
                    <param name="charting.axisY2.minimumNumber">-80</param>
                    <param name="charting.axisY2.maximumNumber">80</param>
                    <param name="charting.axisLabelsY2">#axisLabelsY</param>
                    <param name="charting.axisLabelsY2.axis">@axisY2</param>
                    <param name="charting.axisLabelsY2.placement">right</param>

Now we need to tell splunk how to get the data for each chart:

                    <param name="charting.data0">results</param>
                    <param name="charting.data0.jobID">@data.jobID</param>

The 2 lines above tell splunk to use the base data from the saved search and send it to a new definition data0

After Data0's defined, we're going to establish which columns are used for what chart:

                    <param name="charting.data1">view</param>
                    <param name="charting.data1.table">@data0</param>
                    <param name="charting.data1.columns">[0,1]</param>

The above tells splunk to create another definition "data1", pull the results from data0, but only to pull first column for the xaxis (time) and then only the 1 column of data in the series.

Now do the same thing for our line chart, but tell splunk to use the 2nd column in the series for the line:

                    <param name="charting.data2">view</param>
                    <param name="charting.data2.table">@data0</param>
                    <param name="charting.data2.columns">[0,2]</param>

Now establish the column chart to use our new data source for it's input:

                    <param name="charting.chart.data">@data1</param>

I then tell the 2nd chart to be a line chart, and I give it a hidden axis incase I ever want to change the scale of my line graph (defined earlier with axisY2):

                    <param name="charting.chart2">line</param>
                    <param name="charting.chart2.axisY">@axisY2</param>

Lastly I set the input mode for the 2nd chart:

                    <param name="charting.chart2.data">@data2</param>

Then tell the layout portion of the charting module to draw2 charts:

                    <param name="charting.layout.charts">[@chart,@chart2]</param>

And then to build my custom axis:

                    <param name="charting.layout.axisTitles">[@axisTitleX,@axisTitleY,@axisTitleY2]</param>

And lastly, draw the graph:

                    <module name="FlashChart">
                            <param name="height">600px</param>
                    </module>
            </module>
    </module>

Hope this helps!

jgasyna
New Member

Whats the actual search string? What does HTAnalytics_RollingDelta_Data resolve to?

Thanks.

0 Karma

V_at_Splunk
Splunk Employee
Splunk Employee

We have 2 different Y axes, and they share 1 X-axis. As a concrete example (this is simplified XML),

<searchTemplate> metric=$longevityOngoingMetric$ OR metric=~feedKBPS
| FILLNULL value="*" | EVAL metric_and_indexer = metric . " at " . indexer
| CHART avg(value) BY hours, metric_and_indexer </searchTemplate>

; longevityOngoingMetric is one of {avg|tcp|udp}EPS. Clearly, ~feedKBPS events should have one Y-axis, and the *EPS events should have another. We have events split between 2 charts, and those charts need to be overlaid.

Note that ~feedKBPS sorts lexicographically after any "normal" metrics, so its chart is second: chart2. The remaining events go into first chart, chart1.

Normally, chart1 is the only chart, and the 1 is implied; so you might see corresponding properties foo and foo2, which really means foo1 and foo2.

So, here is the chart element:

    <chart>
        <option name="charting.chart">line</option>
        <option name="charting.chart.nullValueMode">connect</option>
        <option name="charting.axisTitleX.text">hours from test start</option>
        <option name="charting.axisTitleY.text">some kind of EPS</option>
        <option name="charting.axisTitleY2">axisTitle</option>
        <option name="charting.axisTitleY2.text">feed rate, KBPS</option>
        <option name="charting.axisY2">#axisY</option>
        <option name="charting.axisLabelsY2">#axisLabelsY</option>
        <option name="charting.axisLabelsY2.axis">@axisY2</option>
        <option name="charting.axisLabelsY2.placement">right</option>
        <option name="charting.data1">view</option>
        <option name="charting.data1.table">@data</option>
        <option name="charting.data1.columns">[0,1:10]</option>
        <option name="charting.data2">view</option>
        <option name="charting.data2.table">@data</option>
        <option name="charting.data2.columns">[0,11]</option>
        <option name="charting.chart.data">@data1</option>
        <option name="charting.chart2">#chart</option>
        <option name="charting.chart2.axisY">@axisY2</option>
        <option name="charting.chart2.data">@data2</option>
        <option name="charting.layout.charts">[@chart,@chart2]</option>
        <option name="charting.layout.axisLabels">[@axisLabelsX,@axisLabelsY,@axisLabelsY2]</option>
        <option name="charting.layout.axisTitles">[@axisTitleX,@axisTitleY,@axisTitleY2]</option>
    </chart>

A few notes on this:

  • it's helpful to run the query from CLI, and see the tabular output; that will make the idea of "columns" clear in this context.
  • we have 10 indexers, so there will be 10 columns pertaining to the 1st (left) Y-axis. That is why you see <option name="charting.data1.columns">[0,1:10]</option>; the 1:10 specifies the first 10 columns, in starting-with-1 array segment notation. (In a Pascal-meets-Python kind of way.)
  • ~feedKBPS is only 1 column, so that is why you see <option name="charting.data2.columns">[0,11]</option>; the 11 specifies the 11th column.
  • equivalent of <option name="charting.chart.nullValueMode">connect</option> for chart2, would be <option name="charting.chart2.nullValueMode">connect</option>
  • if you only have 2 columns (and not 11), then there would simply be:
    <option name="charting.data1.columns">[0,1]</option>
    ...
    <option name="charting.data2.columns">[0,2]</option>
  • image of resulting report:

alt text

(some details differ from simplified explanation above)

gkanapathy
Splunk Employee
Splunk Employee

I'm pretty sure that you can not do this. It would be interesting to know what in the docs suggested to you that it was.

0 Karma

john_loch
Explorer

Here's an extract from the Advanced configuration - Layout page..

For example, say you want to define two charts where one overlays the other so that they share the same x-axis, but have different y-axes (one on the left side of the chart, and another on the right side of the chart). You would start by defining two custom chart types, chart1 and chart2. We can configure the charts list to render those custom charts instead of the default chart:

[@chart1,@chart2]

More information about configuring multiple charts that share axes is coming soon

0 Karma
Get Updates on the Splunk Community!

This Week's Community Digest - Splunk Community Happenings [9.26.22]

Get the latest news and updates from the Splunk Community here! Upcoming User Group Events! &#x1f44f; Check ...

BSides Splunk 2022 - The Call for Papers is now Open!

TLDR; Main Site: https://bsidessplunk.com CFP Site: https://bsidessplunk.com/cfp CFP Opens: December 15th, ...

Sending Metrics to Splunk Enterprise With the OpenTelemetry Collector

This blog post is part of an ongoing series on OpenTelemetry. The OpenTelemetry project is the second largest ...