With the
release of the BP1 SampleApp V207, I’ve taken a moment to dissect
the usage of the D3.js calendar contained within since it is one of the
examples frequently pointed out to showcase new visualisation capabilities.
Let’s dive a bit deeper into this to understand the way the D3 calendar works and what is necessary to embed this
in any other OBIEE installation.
As-Is in
the Answers Criteria block, the analysis is quite straight-forward. “Color Low”
and “Color High” being simply presentation variables grabbing the values passed
from the “Red / Green Color Limit” prompts on the dashboard page.
The actual
functionality of the D3 calendar is contained and controlled by the two narrative
views of the analysis which I will be calling the “Context Narrative” and “Content
Narrative” respectively for the purpose of this post:


Key here are
the four JavaScript variables which will be used by the code within the content
narrative below. These are filled by the values collected from the 1st
line of the analysis data set (Rows to display = 1). Generally, when analysing
the D3.js examples, it is hugely helpful to add a simple table view to the
analysis in order to see what the data stream actually brings along from the OBI
server since most examples use mixtures of column references and variables.

IMPORTANT: year_range2 must always be the end year +1!
You don’t
have to provide these values through dashboard prompts and simply read the from
the data set, but having a means to restrict the data displayed is always comfortable.



<script type=”text/javascript” src=”/analyticsRes/d3/d3.v2.js”></script>
    <link type=”text/css” rel=”stylesheet” href=”/analyticsRes/d3/lib/colorbrewer/colorbrewer.css”/>
    <link type=”text/css” rel=”stylesheet” href=”/analyticsRes/d3/examples/calendar/calendar.css”/>

    <div id=”my_chart”></div>
    <script type=”text/javascript”>
var margin = {top: 19, right: 20, bottom: 20, left: 19},
    width = @{Width}{720}- margin.right – margin.left, // width
    height = @{Height}{136} – margin.top – margin.bottom, // height
    cellSize = @{CellSize}{12}; // cell size

var day = d3.time.format(“%w”),
    week = d3.time.format(“%U”),
    percent = d3.format(“.1%”),
    format = d3.time.format(“%Y-%m-%d”);

var color = d3.scale.quantize()

var svg = d3.select(“#my_chart”).selectAll(“svg”)
    .data(d3.range(year_range1, year_range2))
    .attr(“width”, width + margin.right + margin.left)
    .attr(“height”, height + margin.top + margin.bottom)
    .attr(“class”, “RdYlGn”)
    .attr(“transform”, “translate(” + (margin.left + (width – cellSize * 53) / 2) + “,” + (margin.top + (height – cellSize * 7) / 2) + “)”);
    .attr(“transform”, “translate(-6,” + cellSize * 3.5 + “)rotate(-90)”)
    .attr(“text-anchor”, “middle”)
var rect = svg.selectAll(“rect.day”)
    .data(function(d) { return d3.time.days(new Date(d, 0, 1), new Date(d + 1, 0, 1)); })
    .attr(“class”, “day”)
    .attr(“width”, cellSize)
    .attr(“height”, cellSize)
    .attr(“x”, function(d) { return week(d) * cellSize; })
    .attr(“y”, function(d) { return day(d) * cellSize; })
    .text(function(d) { return d; });
    .data(function(d) { return d3.time.months(new Date(d, 0, 1), new Date(d + 1, 0, 1)); })
    .attr(“class”, “month”)
    .attr(“d”, monthPath);

    var csv =[];


What happens
here that I can influence?
controls the size of the rendered calendar. Parameters are passed from the dashboard
prompt via presentation variables. If you don’t want users to be able to choose
this, simply put static values.
Date format
is controlled here. VERY IMPORTANT: you must match the date format in this part
of the script to the date format provided within the data set:
means “format
= d3.time.format(“%Y-%m-%d”);”
If your
date picture is for example DD.MM.YYYY (e.g. 14.08.2012), then you need to
adjust the script to:
format = d3.time.format(“%d.%m.%Y “);

the colour limits (.domain) as retrieved by the dashboard prompts.

the display of the year number in front of the rectangles representing the
Leave the
rest as-is.
retrieves the values for date and measure from the data set (per row!). Leave
this as-is.
  var data = d3.nest()
    .key(function(d) { return d.Date; })
    .rollup(function(d) { return d[0].Metric/100; })

  rect.filter(function(d) { return d in data; })
      .attr(“class”, function(d) { return “day q” + color(data[d]) + “-9”; })
      .text(function(d) { return d + “: ” + percent(data[d]); });

function monthPath(t0) {
  var t1 = new Date(t0.getFullYear(), t0.getMonth() + 1, 0),
      d0 = +day(t0), w0 = +week(t0),
      d1 = +day(t1), w1 = +week(t1);
  return “M” + (w0 + 1) * cellSize + “,” + d0 * cellSize
      + “H” + w0 * cellSize + “V” + 7 * cellSize
      + “H” + w1 * cellSize + “V” + (d1 + 1) * cellSize
      + “H” + (w1 + 1) * cellSize + “V” + 0
      + “H” + (w0 + 1) * cellSize + “Z”;

What happens
here that I can influence?
For the SampleApp
example, this transforms the values retrieved from the data set into an index representation
for transformation into a percentile representation in the tooltip display.
If you want absolute
values, simply change
“.rollup(function(d) {
return d[0].Metric/100; })”
“.rollup(function(d) {
return d[0].Metric; })”

This colours the date
rectangles and the actual tooltip with date information and the added percentile
representation of the measure. Here, if you want absolute values, simply change
“.text(function(d) {
return d + “: ” + percent(data[d]); });”
“.text(function(d) {
return d + “: ” + data[d] });”
Leave the rest as-is.
So what do you need
all-in-all to transplant this into any OBIEE implementation?

1.) The
D3 libraries contained in the d3 and d3-cloud folders. Quickest way – if you
have the SampleApp lying around – is to just grab them from the analyticsRes
folder of the VirtualBox and slap them into your own analyticsRes

2.) An
analysis on the date (day!) grain with some measure. Since you can either
hard-code the time ranges, size and colour limits, those two are really the
bare minimum for this D3 calendar to work.
That’s it. Bob’s your

UPDATE: Since the D3.js libraries are only dependent of the final browser interpreting the generated code (IE8 will NOT work!), you can transplant this into any version of OBIEE that you fancy. This functionality is NOT tied to OBIEE


A while back our oraclenerd had a question about presentation server cache settings which he sent out through twitter.

rnm1978 and me answered to his distress call (emails not included. twitter’s quite useless for sending instanceconfig.xml subsets ;-)).

However, I wanted to make it clear through this post, what part of the presentation server cache is actually managed by which parameter since there’s a little gotcha in there.
So basically we there are four parameter which exist for the presentation servers instanceconfig.xml (see also Johns pdf extract). By default they’re not explicitly noted in the file so you need to specify them in order to change them. Here’s a little sample with already modified paths:

Now normally the cache files for the presentation server reside in the tmp directory within the respective subdirectories sawcharts, sawrptcache and sawvc; with the xml cache files lying in the tmp folder itself. Note that I cleaned out all files in the directory for in the screenshot below to have a clean testing baseline:

Restarting the presentation server with the additional XML above gives me the following results:

Chart cache:

Report cache:

State pool cache:

XML cache:

XML cache empty? Aha, seems there’s an issue. Let’s check the original path:

The XML cache files are still here. Not really what we wanted. So the XMLCacheDefault CacheDirectory seems to be useless. At this point I actually created an SR on MyOracleSupport to confirm a hunch I had. Result:
“With regards the parameter , I have researched this and have not found any documentation on it, internally or published. Infact through my research it appears that it has never been the case that this parameter is used to determine the path of the nqsxxxx temp files.
Previous versions of OBI i.e. Siebel Analytics document that the temp files generated by the Analytics Web server could be redirected by using the parameter ‘TempDir’ in Instance config or as a registry variable, in conjunction with the work directory path.”

So off to the NQSConfig.ini and change the WORK_DIRECTORY_PATHS:

#WORK_DIRECTORY_PATHS = “C:OracleOracleBIDatatmp”;
WORK_DIRECTORY_PATHS = “C:DataSourcesCachetmp”;

After that, restart all the services and check again where the cache files went.

Ok now we know how to make the rest of the cache files elsewhere.