JasperReports Server Visualize - Js Guide
JasperReports Server Visualize - Js Guide
VISUALIZE.JS GUIDE
RELEASE 6.1
http://www.jaspersoft.com
Copyright 2005-2015, TIBCO Software Inc. All rights reserved. Printed in the U.S.A. TIBCO, the TIBCO
logo, TIBCO Jaspersoft, the TIBCO Jaspersoft logo, TIBCO Jaspersoft iReport Designer, TIBCO JasperReports
Library, TIBCO JasperReports Server, TIBCO Jaspersoft OLAP, TIBCO Jaspersoft Studio, and TIBCO Jaspersoft
ETL are trademarks and/or registered trademarks of TIBCO Software Inc. in the United States and in
jurisdictions throughout the world. All other company and product names are or may be trade names or
trademarks of their respective owners.
This is version 0515-JSP61-03 of the JasperReports Server Visualize.js Guide.
TABLE OF CONTENTS
Chapter 1 API Reference - Visualize.js
7
8
9
11
Authentication Properties
Login With Plain Text Credentials
Login With SSO Token
Logging Out
Login With Hooks
UI for Login/Logout
UI for Login/Logout With SSO Token
Sharing Credentials Between Calls
Using Visualize.js Without Authentication
11
13
13
14
14
15
16
16
17
19
3.1
3.2
3.3
3.4
3.5
3.6
Search Properties
Search Functions
Finding Resources
Reusing a Search Instance
Reusing Search Results
Discovering Available Types
Report Properties
Report Functions
Report Structure
Rendering a Report
Setting Report Parameters
Rendering Multiple Reports
Setting Report Pagination
Creating Pagination Controls (Next/Previous)
Creating Pagination Controls (Range)
19
21
22
23
23
23
25
25
28
31
32
33
34
35
35
36
4.10
4.11
4.12
4.13
Dashboard Properties
Dashboard Functions
Dashboard Structure
Rendering a Dashboard
Refreshing a Dashboard
Using Dashboard Parameters
Setting Dashboard Hyperlink Options
Closing a Dashboard
Error Properties
Common Errors
Catching Initialization and Authentication Errors
Catching Search Errors
Validating Search Properties
Catching Report Errors
Catching Input Control Errors
Validating Input Controls
36
38
39
40
43
43
44
44
45
45
46
47
47
49
49
50
52
52
53
53
56
59
61
61
62
62
63
63
64
64
65
67
67
68
68
68
71
Structure of Hyperlinks
Customizing Links
Drill-Down in Separate Containers
Accessing Data In Links
71
72
73
74
77
77
80
82
83
85
86
88
92
93
95
96
97
97
99
107
CHAPTER 1
The JavaScript API exposed through Visualize.js allows you to embed and programmatically interact with
reports dynamically. With Visualize.js, you can create web pages and web applications that seamlessly embed
reports and complex interaction. You can control the look and feel of all elements through CSS and invent new
ways to merge data into your application. Visualize.js helps you make advanced business intelligence available
to your users.
This chapter contains the following sections:
API Reference
API Reference
API Reference
API Reference
1.1
The content of visualize.js is type='text/javascript', but that is the default so you usually don't need to
include it.
Type
Description
userLocale
locale string
logEnabled
true|false
logLevel
debug|info|warn|error
baseUrl
URL
_opt
true|false
1.2
You write JavaScript in a callback that controls what the client does. The following code sample shows the
functions of the JrsClient that are available to you:
{
/**
* Perform authentification with provided auth object
* @param auth {object} - auth properties
* @returns {Deferred} dfd
*/
login : function(auth){},
/**
* Destroy current auth session
* @returns {Deferred} dfd
*/
logout : function() {},
/**
* Create and run report component with provided properties
* @param properties {object} - report properties
* @returns {Report} report - instance of Report
*/
report : function(properties){},
/**
* Create and run controls for provided controls properties
* @param properties {object} - input controls properties
* @returns {Options} inputControls instance
*
*/
inputControls : function(properties){},
/**
* Create and run resource search component for provided properties
* @param properties {object} - search properties
* @returns {Options} resourcesSearch instance
*
*/
resourcesSearch : function(properties){}
}
1.3
Usage Patterns
After specifying the authentication information, you write the callback that will execute inside the client
provided by visualize.js.
visualize({
server: "http://bi.example.com",
auth: {
name : "joeuser",
password: "joeuser"
}
}, function(v){
//'v' it's a client to JRS instance under
//session established for joeuser/joeuser
"http://bi.example.com"
If you prefer, you can use the deferred pattern instead of the callback:
visualize({
server: "http://bi.example.com",
auth: {
name : "joeuser",
password: "joeuser"
}
}).done(function(v){
//'v' it's a client to JRS instance under
//session established for joeuser/joeuser
"http://bi.example.com"
10
CHAPTER 2
The initialization of the script sets the authentication method and credentials that you want to use for accessing
JasperReports Server. You can then use the login and logout functions to manage multiple user sessions.
This chapter contains the following sections:
2.1
Authentication Properties
Login With Plain Text Credentials
Login With SSO Token
Logging Out
Login With Hooks
UI for Login/Logout
UI for Login/Logout With SSO Token
Sharing Credentials Between Calls
Using Visualize.js Without Authentication
Authentication Properties
The properties argument to the visualize function has all the fields for specifying various authentication
methods.
{
"oneOf": [
{
"type": "object",
"description": "Visualize main properties",
"properties": {
"server": {
"type": "string",
"description": "Url to JRS instance."
},
"auth": {
"description": "Authentication Properties",
"type": "object",
"oneOf": [
{
"properties": {
"token": {
11
"type": "string",
"description": "SSO authentication token"
},
"headers": {
"type": "object",
"description": "HTTP header parameters"
},
"queryParams": {
"type": "object",
"description": "HTTP query parameters"
}
},
"additionalProperties" : false,
"required": ["token"]
},
{
"properties": {
"name": {
"type": "string",
"description": "Name of the user to authenticate"
},
"password": {
"type": "string",
"description": "Password of the user to authenticate"
},
"organization": {
"type": "string",
"description": "Organization of the user to authenticate"
},
"timezone": {
"type": "string",
"description": "Default user timezone to use for this session"
},
"headers": {
"type": "object",
"description": "HTTP header parameters"
},
"queryParams": {
"type": "object",
"description": "HTTP query parameters"
}
},
"additionalProperties" : false,
"required": ["name", "password"]
}
]
}
},
"required": ["server", "auth"]
},
{
"$ref": "#/definitions/func"
}
],
"definitions": {
"func" : {
12
There are several ways to set the user credentials, based on your environment.
2.2
2.3
Some SSO mechanisms require encoding, or additional parameters, or both. For example, if your server is
configured for pre-authentication, you could use the following example to authenticate from Visualize.js. Note
that the encoded fields depend on the specifics of your pre-authentication configuration:
var t = encodeURIComponent("u=John|r=Ext_User|o=organization_1|pa1=USA|pa2=1");
visualize({
auth: {
token: t,
preAuth: true,
13
tokenName: "pp"
}
}, function (v){
...
});
2.4
Logging Out
To log out and destroy the current user session, call the logout function and optionally specify any action to
take when done.
visualize({
auth: {
name: "jasperadmin",
password: "jasperadmin",
}
}, function (v) {
...
//destroy session
$("#logout").click(function () {
v.logout().done(function () {
alert("You are now logged out of JasperReports Server.");
});
});
});
2.5
14
}
}, function (v) {
...
});
2.6
UI for Login/Logout
You can define IDs (#name) with listeners that perform login and logout functions. In your HTML, you can then
assign these IDs to the appropriate buttons or links.
visualize(
function(v){
$("#selected_resource").change(function () {
$("#container").html("");
createReport($("#selected_resource").val(), v);
});
$("#login").click(function(){
v.login(getAuthData()).done(function(){
createReport($("#selected_resource").val(),v);
showMessage(".success");
}).fail(function(){showMessage(".error");});
});
$("#logout").click(function(){
v.logout().done(function(){showMessage(".logout");});
});
$(':disabled').prop('disabled', false);
}
);
//create and render report to specific container
function createReport(uri, v) {
v("#container").report({
resource: uri,
error: function (err) {
alert(err.message);
}
});
};
function showMessage(selector){
$(".message").hide();
$(selector).show();
};
function getAuthData(){
return {name: $("#j_username").val(),
password: $("#j_password").val(),
organization:$("#orgId").val(),
locale:$("#userLocale").val(),
timezone:$("#userTimezone").val()
}
};
15
2.7
2.8
16
organization:"organization_1",
timezone: "Europe/Helsinki"
}
});
visualize(function (v) {
v("#container1").report({
resource: "/public/Samples/Reports/06g.ProfitDetailReport",
error: function (err) {
alert(err.message);
}
});
});
visualize(function (v) {
v("#container2").report({
resource: "/public/Samples/Reports/State_Performance",
error: function (err) {
alert(err.message);
}
});
});
2.9
17
18
CHAPTER 3
The resourcesSearch function performs searches in the repository to find content that can be displayed by
visualize.js.
This chapter contains the following sections:
3.1
Search Properties
Search Functions
Finding Resources
Reusing a Search Instance
Reusing Search Results
Discovering Available Types
Search Properties
The properties structure passed to the resourcesSearch function is defined as follows:
{
"type": "object",
"properties": {
"server": {
"type": "string",
"description": "Url to JRS instance."
},
"q": {
"type": "string",
"description": "Query string. Search for occurrence in label or description of resource."
},
"folderUri": {
"type": "string",
"description": "Parent folder URI.",
"pattern": "^/\\w*(/\\w+)*$"
},
"type": {
"type": "string",
"description": "Type of resources to search.",
19
"enum": [
"folder", "dataType", "jdbcDataSource", "awsDataSource", "jndiJdbcDataSource",
"virtualDataSource", "customDataSource", "beanDataSource", "xmlaConnection",
"listOfValues", "file", "reportOptions", "dashboard", "adhocDataView",
"query", "olapUnit", "reportUnit", "domainTopic", "semanticLayerDataSource",
"secureMondrianConnection", "mondrianXmlaDefinition", "mondrianConnection",
"inputControl"
]
},
"offset": {
"type": "integer",
"description": "Pagination. Index of first resource to show.",
"minimum": 0
},
"limit": {
"type": "integer",
"description": "Pagination. Resources count per page.",
"minimum": 0
},
"recursive": {
"type": "boolean",
"description": "Flag indicates if search should be recursive."
},
"sortBy": {
"type": "string",
"description": "Field to sort on.",
"enum": [
"uri",
"label",
"description",
"type",
"creationDate",
"updateDate",
"accessTime",
"popularity"
]
},
"accessType": {
"type": "string",
"description": "Filtering by type of access, e.g. what was done with resource.",
"enum": [
"viewed",
"modified"
]
},
"showHiddenItems": {
"type": "boolean",
"description": "Flag indicates if hidden items should present in results."
},
"forceTotalCount": {
"type": "boolean",
"description": "If true, Total-Count header is always set (impact on performance),
otherwise - in first page only"
}
},
"required": ["server"]
}
20
3.2
Search Functions
The resourcesSearch function exposes the following functions:
define(function () {
/**
* Constructor. Takes context as argument.
* @param contextObj - map of properties.
*/
function ResourcesSearch(contextObj){};
/**
* Get/Set 'q' parameter of the query
* @param contextObj - map of properties.
* @returns this if 'value' sent to the method,
*
otherwise returns current value of the parameter
*/
ResourcesSearch.prototype.q= function(value){};
/**
* Get/Set 'folderUri' parameter of the query
* @param value - new value, optional
* @returns this if 'value' sent to the method,
*
otherwise returns current value of the parameter
*/
ResourcesSearch.prototype.folderUri= function(value){};
/**
* Get/Set 'type' parameter of the query
* @param value - new value, optional
* @returns this if 'value' sent to the method,
*
otherwise returns current value of the parameter
*/
ResourcesSearch.prototype.type= function(value){};
/**
* Get/Set 'offset' parameter of the query
* @param value - new value, optional
* @returns this if 'value' sent to the method,
*
otherwise returns current value of the parameter
*/
ResourcesSearch.prototype.offset= function(value){};
/**
* Get/Set 'limit' parameter of the query
* @param value - new value, optional
* @returns this if 'value' sent to the method,
*
otherwise returns current value of the parameter
*/
ResourcesSearch.prototype.limit= function(value){};
/**
* Get/Set 'recursive' parameter of the query
* @param value - new value, optional
* @returns this if 'value' sent to the method,
*
otherwise returns current value of the parameter
21
*/
ResourcesSearch.prototype.recursive= function(value){};
/**
* Get/Set 'sortBy' parameter of the query
* @param value - new value, optional
* @returns this if 'value' sent to the method,
*
otherwise returns current value of the parameter
*/
ResourcesSearch.prototype.sortBy= function(value){};
/**
* Get/Set 'accessType' parameter of the query
* @param value - new value, optional
* @returns this if 'value' sent to the method,
*
otherwise returns current value of the parameter
*/
ResourcesSearch.prototype.accessType= function(value){};
/**
* Get/Set 'showHiddenItems' parameter of the query
* @param value - new value, optional
* @returns this if 'value' sent to the method,
*
otherwise returns current value of the parameter
*/
ResourcesSearch.prototype.showHiddenItems= function(value){};
/**
* Get/Set 'forceTotalCount' parameter of the query
* @param value - new value, optional
* @returns this if 'value' sent to the method,
*
otherwise returns current value of the parameter
*/
ResourcesSearch.prototype.forceTotalCount= function(value){};
return ResourcesSearch;
});
3.3
Finding Resources
The following code examples show two different ways of handling results after making a simple repository
search in the Public folder.
new ResourcesSearch({
server:"http://localhost:8080/jasperserver-pro",
folderUri: "/public",
recursive: false
})).run(function(resourceLookups){
// results here
});
22
recursive: false
success: function(repo) {
console.log(repo.data()); // resourceLookups
}
});
3.4
3.5
3.6
23
organization: "organization_1"
}
}, function (v) {
buildControl("Resources types", v.resourcesSearch.types);
buildControl("Resources search sort types", v.resourcesSearch.sortBy);
});
function buildControl(name, options) {
function buildOptions(options) {
var template = "<option>{value}</option>";
return options.reduce(function (memo, option) {
return memo + template.replace("{value}", option);
}, "")
}
console.log(options);
if (!options.length){
console.log(options);
}
var template = "<label>{label}</label><select>{options}</select><br>",
content = template.replace("{label}", name)
.replace("{options}", buildOptions(options));
$("#container").append($(content));
}
24
CHAPTER 4
The report function runs reports on JasperReports Server and displays the result in a container that you
provide.
This chapter contains the following sections:
4.1
Report Properties
Report Functions
Report Structure
Rendering a Report
Setting Report Parameters
Rendering Multiple Reports
Setting Report Pagination
Creating Pagination Controls (Next/Previous)
Creating Pagination Controls (Range)
Exporting From a Report
Refreshing a Report
Canceling Report Execution
Discovering Available Charts and Formats
Report Properties
The properties structure passed to the report function is defined as follows:
{
"title": "Report Properties",
"description": "A JSON Schema describing a Report Properties",
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"server": {
"type": "string",
"description": "URL of JRS instance."
},
"resource": {
"type": "string",
"description": "Report resource URI.",
25
"pattern": "^/[^/~!#\\$%^|\\s`@&*()\\+={}\\[\\]:;\"'<>,?/\\|\\\\]+(/[^/~!#\\$%^|\\s`@&*()
\\+={}\\[\\]:;\"'<>,?/\\|\\\\]+)*$"
},
"container": {
"type": "string",
"description": "CSS selector for container to render report to."
},
"params": {
"$ref": "#/definitions/params"
},
"pages": {
"type": ["string", "integer"],
"description": "Range of report's pages or single report page",
"pattern": "^\\d+(\\-\\d+)?$",
"default": 1
},
"linkOptions": {
"type": "object",
"description": "Customization for report's links",
"properties": {
"beforeRender": {
"$ref": "#/definitions/Function",
"description": "Allows to change any link representation before report would be
rendered"
},
"events": {
"$ref": "#/definitions/eventsMapper",
"description": "Allow to add listener by specific events to links representations
by link name"
}
}
},
"defaultJiveUi" : {
"type": "object",
"description": "Control default JIVE UI in report",
"properties": {
"enabled": {
"type": "boolean",
"default": false
},
"onError":{
"$ref": "#/definitions/Function",
"description": "Jive UI error listener"
}
}
},
"isolateDom": {
"type": "boolean",
"description": "Isolate report's DOM from third-party page CSS. Can't be set while default
JIVE UI is enabled",
"default": false
}
},
"required": ["server", "resource"],
"definitions": {
"params": {
26
"type": "object",
"description": "Report's parameters values",
"additionalProperties": {
"type": "array"
}
},
"ExportOptions": {
"title": "Report export options",
"type": "object",
"properties": {
"outputFormat": {
"enum": [
"pdf",
"xlsx",
"xls",
"rtf",
"csv",
"xml",
"odt",
"ods",
"docx"
]
},
"pages": {
"type": ["string", "integer"],
"description": "Exports all pages if this property was not specified. Range of
report's pages or single report page",
"pattern": "^\\d+(\\-\\d+)?$"
},
"paginated": {
"type": "boolean",
"description": "Control 'pagination' feature. Only 'xls' and 'xlsx' support it",
"default": "false"
}
},
"required": ["outputFormat"]
},
"Function": {
"type": "object",
"description": "JavaScript Function"
},
"eventsMapper": {
"type": "object",
"description": "Map events by name to user defined handler. For example: 'click',
'focus', etc ",
"additionalProperties": {
"$ref": "#/definitions/Function"
}
},
"chartComponent": {
"description": "JIVE chart component schema",
"properties": {
"id": {
"type": "string",
"description": "Chart component identifier"
27
},
"componentType": {
"enum": ["chart"]
},
"chartType": {
"description": "Special chart's type",
"enum": [
"Bar", "Column", "Line", "Area", "Spline",
"AreaSpline", "StackedBar", "StackedColumn", "StackedLine", "StackedArea",
"StackedSpline", "StackedAreaSpline", "StackedPercentBar",
"StackedPercentColumn", "StackedPercentLine", "StackedPercentArea",
"StackedPercentSpline", "StackedPercentAreaSpline", "Pie", "DualLevelPie",
"TimeSeriesLine", "TimeSeriesArea", "TimeSeriesSpline",
"TimeSeriesAreaSpline", "ColumnLine", "ColumnSpline", "StackedColumnLine",
"StackedColumnSpline", "MultiAxisLine", "MultiAxisSpline", "MultiAxisColumn",
"Scatter", "Bubble", "SpiderColumn", "SpiderLine", "SpiderArea"
]
}
},
"required": ["id"]
}
}
}
4.2
Report Functions
The report function exposes the following functions:
define(function () {
/**
* @param {Object} properties - report properties
* @constructor
*/
function Report(properties){}
/**
* Setters and Getters are functions around
* schema for bi component at ./schema/ReportSchema.json
* Each setter returns pointer to 'this' to provide chainable API
*/
//Special
getters
/**
* Get any result after invoking run action, 'null' by default
* @returns any data which supported by this bi component
*/
Report.prototype.data = function(){};
// Special setters
/**
* Attaches event handlers to some specific events.
* New events overwrite old ones.
28
* @param {Object} events - object containing event names as keys and event handlers as values
* @return {Report} report - current Report instance (allows chaining)
*/
Report.prototype.events = function(events){};
//Actions
/**
* Perform main action for bi component
* Callbacks will be attached to deferred object.
*
* @param {Function} callback - optional, invoked in case of successful run
* @param {Function} errorback - optional, invoked in case of failed run
* @param {Function} always - optional, invoked always
* @return {Deferred} dfd
*/
Report.prototype.run = function(callback, errorback, always){};
/**
* Render report to container, previously specified in property.
* Clean up all content of container before adding Report's content
* @param {Function} callback - optional, invoked in case successful export
* @param {Function} errorback - optional, invoked in case of failed export
* @param {Function} always - optional, optional, invoked always
* @return {Deferred} dfd
*/
Report.prototype.render = function(callback, errorback, always){};
/**
* Cancel report execution
* @param {Function} callback - optional, invoked in case of successful cancel
* @param {Function} errorback - optional, invoked in case of failed cancel
* @param {Function} always - optional, invoked optional, invoked always
* @return {Deferred} dfd
*/
Report.prototype.cancel = function(callback, errorback, always){};
/**
* Update report's component
* @param {Object} component - jive component to update, should have id field
* @param {Function} callback - optional, invoked in case of successful update
* @param {Function} errorback - optional, invoked in case of failed update
* @param {Function} always - optional, invoked optional, invoked always
* @return {Deferred} dfd
*/
Report.prototype.updateComponent = function(component, callback, errorback, always){};
/**
* Update
* @param
* @param
* @param
* @param
* @param
report's component
{String} id - jive component id
{Object} properties - jive component's properties to update
{Function} callback - optional, invoked in case of successful update
{Function} errorback - optional, invoked in case of failed update
{Function} always - optional, invoked optional, invoked always
29
* @return{Deferred} dfd
*/
Report.prototype.updateComponent = function(id, properties, callback, errorback, always){};
/**
* Undo previous JIVE component update
* @param {Function} callback - optional, invoked in case of successful update
* @param {Function} errorback - optional, invoked in case of failed update
* @param {Function} always - optional, invoked optional, invoked always
* @return{Deferred} dfd
*/
Report.prototype.undo = function(callback, errorback, always){};
/**
* Reset report to initial state
* @param {Function} callback - optional, invoked in case of successful update
* @param {Function} errorback - optional, invoked in case of failed update
* @param {Function} always - optional, invoked optional, invoked always
* @return{Deferred} dfd
*/
Report.prototype.undoAll = function(callback, errorback, always){};
/**
* Redo next JIVE component update
* @param {Function} callback - optional, invoked in case of successful update
* @param {Function} errorback - optional, invoked in case of failed update
* @param {Function} always - optional, invoked optional, invoked always
* @return{Deferred} dfd
*/
Report.prototype.redo = function(callback, errorback, always){};
/**
* Export report to specific format, execute only after report run action is finished
* @param {ExportOptions} exportOptions - export options
* @param {Function} callback - optional, invoked with link object
* @param {Function} errorback - optional, invoked in case of failed export
* @param {Function} always - optional, invoked optional, invoked always
* @return{Deferred} dfd
*/
Report.prototype.export = function(exportOptions, callback, errorback, always){};
/**
* Cancel all execution, destroy report representation if any, leave only
* properties
* @param {Function} callback - optional, invoked in case of successful cleanup
* @param {Function} errorback - optional, invoked in case of failed cleanup
* @param {Function} always - optional, invoked optional, invoked always
* @return {Deferred} dfd
*/
Report.prototype.destroy = function(callback, errorback, always){};
return Report;
});
30
4.3
Report Structure
The Report Data structure represents the rendered report object manipulated by the report function. Even though
it is named "data," it does not contain report data, but rather the data about the report. For example, the Report
Data structure contains information about the links in the report, as explained in Customizing Links on
page72, and components of the JIVE UI, as explained in Interacting With JIVE UI Components on
page77.
{
"title": "Report Data",
"description": "A JSON Schema describing a Report Data",
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"totalPages": {
"type": "number",
"description": "Report's page total count"
},
"links": {
"type": "array",
"description": "Links extracted from markup, so their quantity depends from pages you have
requested",
"items": {
"$ref": "#/definitions/jrLink"
}
},
"components": {
"type": "array",
"description": "Components in report, their quantity depends from pages you have
requested",
"items": {
"type": "object",
"description": "JIVE components data"
}
}
},
"definitions": {
"jrLink": {
"title": "JR Hyperlink",
"type": "object",
"properties": {
"type": {
"oneOf": [
{
"$ref": "#/definitions/linkTypeReference"
},
{
"$ref": "#/definitions/linkTypeReportExecution"
}
]
},
"tooltip": {
"type": "string",
"description": "Hyperlink tooltip"
},
"href": {
31
"type": "string",
"description": "Hyperlink reference"
},
"parameters": {
"type": "object"
}
},
"required": ["type"],
"definitions": {
"linkTypeReference": {
"enum": ["Reference"],
"description": "The hyperlink points to an external resource."
},
"linkTypeReportExecution": {
"enum": ["ReportExecution"],
"description": "The hyperlink points to JR report"
}
}
}
}
}
4.4
Rendering a Report
To run a report on the server and render it in Visualize.js, create a report object and set its properties. The server
and resource properties determine which report to run, and the container property determines where it appears on
your page.
var report = v.report({
server: "http://bi.example.com:8080/jasperserver-pro",
resource: "/public/Sample/MyReport",
container: "#container"
});
The following code example shows how to display a report that the user selects from a list.
visualize({
auth: { ...
}
}, function (v) {
//render report from provided resource
v("#container").report({
resource: $("#selected_resource").val(),
error: handleError
});
$("#selected_resource").change(function () {
//clean container
$("#container").html("");
//render report from another resource
v("#container").report({
resource: $("#selected_resource").val(),
error:handleError
32
});
});
//enable report chooser
$(':disabled').prop('disabled', false);
//show error
function handleError(err){
alert(err.message);
}
});
The HTML page that displays the report uses a static list of reports in a drop-down selector, but otherwise needs
only a container element.
<!--Provide the URL to visualize.js-->
<script src="http://bi.example.com:8080/jasperserver-pro/client/visualize.js"></script>
<select id="selected_resource" disabled="true" name="report">
<option value="/public/Samples/Reports/1._Geographic_Results_by_Segment_Report">Geographic Results
by Segment</option>
<option value="/public/Samples/Reports/2_Sales_Mix_by_Demographic_Report">Sales Mix by
Demographic</option>
<option value="/public/Samples/Reports/3_Store_Segment_Performance_Report">Store Segment
Performance</option>
<option value="/public/Samples/Reports/04._Product_Results_by_Store_Type_Report">Product Results
by Store Type</option>
</select>
<!--Provide a container to render your visualization-->
<div id="container"></div>
4.5
If a report has required parameters, you must set them in the report object of the initial call, otherwise you'll get
an error. For more information, see Catching Report Errors on page64.
The example above is trivial, but the power of Visualize.js comes from this simple code. You can create any
number of user interfaces, database lookups, or your own calculations to provide the values of parameters. Your
parameters could be based on 3rd party API calls that get triggered from other parts of the page or other pages in
your app. When your reports can respond to dynamic events, they become truly embedded and much more
relevant to the user.
33
4.6
Associated HTML:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.0/jquery-ui.min.js"></script>
<script src="http://bi.example.com:8080/jasperserver-pro/client/visualize.js"></script>
<table class="sample">
<tr>
<td id="container1"></td>
<td id="container2"></td>
</tr>
<tr>
<td id="container3"></td>
<td id="container4"></td>
</tr>
</table>
Associated CSS:
html, body {
}
table.sample {
width: 100%;
}
td#c1, td#c2, td#c3, td#c4 {
width: 50%;
}
34
4.7
4.8
Associated HTML:
35
<script src="http://code.jquery.com/jquery-2.1.0.js"></script>
<script src="http://bi.example.com:8080/jasperserver-pro/client/visualize.js"></script>
<button id="previousPage">Previous Page</button><button id="nextPage">Next Page</button>
<div id="container"></div>
4.9
Associated HTML:
<script src="http://code.jquery.com/jquery-2.1.0.js"></script>
<script src="http://bi.example.com:8080/jasperserver-pro/client/visualize.js"></script>
Page range: <input type="text" id="pageRange"></input>
<div id="container"></div>
36
The following sample exports 10 pages of the report to a paginated Excel spreadsheet:
report.run(exportToPaginatedExcel);
function exportToPaginatedExcel() {
report
.export({
outputFormat: "xls",
pages: "1-10",
paginated: true
})
.done(function(link){
window.open(link.href); // open new window to download report
})
.fail(function(err){
alert(err.message);
});
}
37
Associated HTML:
<script src="http://code.jquery.com/jquery-2.1.0.js"></script>
<!-- Provide the URL to visualize.js -->
<script src="http://bi.example.com:8080/jasperserver-pro/client/visualize.js"></script>
<button id="button" disabled>Export</button>
<!-- Provide a container for the report -->
<div id="container"></div>
38
runImmediately: !alwasyRefresh,
resource: "/public/viz/usersReport",
container: "#container1",
});
if (alwasyRefresh){
report.refresh();
}
$("button").click(function(){
report
.refresh()
.done(function(){console.log("Report Refreshed!");})
.fail(function(){alert("Report Refresh Failed!");});
});
});
Associated HTML:
<script src="http://code.jquery.com/jquery-2.1.0.js"></script>
<script src="http://bi.example.com:8080/jasperserver-pro/client/visualize.js"></script>
<button>Refresh</button>
<div id="container1"></div>
The following example is more complete and creates a UI for a spinner and cancel button for a long-running
report.
var spinner = createSpinner();
visualize({
auth: { ...
}
}, function (v) {
var button = $("button");
var report = v.report({
39
resource: "/public/Reports/Slow_Report",
container: "#container",
events: {
changeTotalPages : function(){
spinner.remove();
}
}
});
button.click(function () {
report
.cancel()
.then(function () {
spinner.remove();
alert("Report Canceled!");
})
.fail(function () {
alert("Can't Cancel Report");
});
});
});
function createSpinner() {
var opts = {
lines: 17, length: 3, width: 2, radius: 3, corners: 0.6, rotate: 0, direction: 1,
color: '#000', speed: 1, trail: 60, shadow: false, hwaccel: false, zIndex: 2e9,
top: 'auto', left: 'auto', className: 'spinner'
};
var container = $("#spinner");
var spinner = new Spinner(opts).spin(container[0]);
return container;
}
Associated HTML:
<script src="http://code.jquery.com/jquery-2.1.0.js"></script>
<script src="http://fgnass.github.io/spin.js/spin.js"></script>
<script src="http://bi.example.com:8080/jasperserver-pro/client/visualize.js"></script>
<div id="spinner"></div>
<button>Cancel</button>
<div id="container"></div>
40
41
42
CHAPTER 5
The inputControls function prepares and displays input controls for reports that your users interact with.
This chapter contains the following sections:
5.1
43
5.2
5.3
44
}
}
],
"state": {
"uri": "/reports/samples/Cascading_multi_select_report_files/Cascading_name_single_select",
"id": "Cascading_name_single_select",
"value": null,
"options": [
{
"selected": false,
"label": "A & U Jaramillo Telecommunications, Inc",
"value": "A & U Jaramillo Telecommunications, Inc"
}
]
}
},
....
]
5.4
5.5
45
visualize({
auth: {
name: "superuser",
password: "superuser"
}
},function(v) {
v.inputControls({
resource: "/public/Samples/Reports/16g.InteractiveSalesReport",
success: function (controls) {
controls.forEach(buildControl);
},
error: function (err) {
alert(err);
}
});
function buildControl(control) {
function buildOptions(options) {
var template = "<option>{value}</option>";
return options.reduce(function (memo, option) {
return memo + template.replace("{value}", option.value);
}, "")
}
var template = "<label>{label}</label><select>{options}</select><br>",
content = template.replace("{label}", control.label)
.replace("{options}", buildOptions(control.state.options));
$("#container").append($(content));
}
});
5.6
46
$("#productFamilySelector").on("change", function() {
report.params({ "Product_Family": [$(this).val()] }).run();
});
});
function renderInputControls(data) {
var productFamilyInputControl = _.findWhere(data, {id: "Product_Family"});
var select = $("#productFamilySelector");
_.each(productFamilyInputControl.state.options, function(option) {
select.append("<option " + (option.selected ? "selected" : "") + " value='" +
option.value + "'>" + option.label + "</option>");
});
}
Associated HTML:
<script src="http://code.jquery.com/jquery-2.1.0.js"></script>
<script src="http://underscorejs.org/underscore-min.js"></script>
<script src="http://bi.example.com:8080/jasperserver-pro/client/visualize.js"></script>
<select id="productFamilySelector"></select>
<div id="container"></div>
5.7
5.8
47
48
CHAPTER 6
The dashboard function runs dashboards on JasperReports Server and displays the result in a container that you
provide. Dashboards are a collection of reports and widgets that you design on the server. Dashboards were
entirely redesigned in JasperReports Server 6.0 to provide stunning data displays and seamless integration
through Visualize.js.
This chapter contains the following sections:
6.1
Dashboard Properties
Dashboard Functions
Dashboard Structure
Rendering a Dashboard
Refreshing a Dashboard
Using Dashboard Parameters
Setting Dashboard Hyperlink Options
Closing a Dashboard
Dashboard Properties
The properties structure passed to the dashboard function is defined as follows:
{
"title": "Dashboard Properties",
"type": "object",
"description": "JSON Schema describing Dashboard Properties",
"$schema": "http://json-schema.org/draft-04/schema#",
"properties": {
"server": {
"type": "string",
"description": "URL of JRS instance"
},
"resource": {
"type": "string",
"description": "Dashboard resource URI",
"pattern": "^/[^/~!#\\$%^|\\s`@&*()\\+={}\\[\\]:;\"'<>,?/\\|\\\\]+(/[^/~!#\\$%^|\\s`@&*()
\\+={}\\[\\]:;\"'<>,?/\\|\\\\]+)*$"
},
49
"container": {
"oneOf": [
{
"type": "object",
"additionalProperties" : true,
"description": "DOM element to render report to"
},
{
"type": "string",
"description": "CSS selector for container to render report to"
}
]
},
"linkOptions": {
"type": "object",
"description": "Dashboard's parameters values",
"properties": {
"beforeRender": {
"type": "function",
"description": "A function to process link - link element pairs."
},
"events": {
"type": "object",
"description": "Backbone-like events object to be applied to JR links",
"additionalProperties" : true
}
}
},
"params": {
"type": "object",
"description": "Dashboard parameter values",
"additionalProperties": {
"type": "array"
}
}
},
"required": ["server", "resource"]
}
6.2
Dashboard Functions
The dashboard function exposes the following functions:
define(function () {
/**
* @param {Object} properties - Dashboard properties
* @constructor
*/
function Dashboard(properties){}
//Special
getters
/**
50
/**
* Refresh Dashboard
* @param {Function} callback - optional, invoked in case of successful refresh
* @param {Function} errorback - optional, invoked in case of failed refresh
* @param {Function} always - optional, invoked optional, invoked always
* @return {Deferred} dfd
*/
Dashboard.prototype.refresh = function(callback, errorback, always){};
/**
* Cancel Dashboard execution
* @param {Function} callback - optional, invoked in case of successful cancel
* @param {Function} errorback - optional, invoked in case of failed cancel
* @param {Function} always - optional, invoked optional, invoked always
* @return {Deferred} dfd
*/
Dashboard.prototype.cancel = function(callback, errorback, always){};
/**
* Cancel all executions, destroy Dashboard representation if any, leave only
* properties
* @param {Function} callback - optional, invoked in case of successful cleanup
* @param {Function} errorback - optional, invoked in case of failed cleanup
* @param {Function} always - optional, invoked optional, invoked always
* @return {Deferred} dfd
*/
Dashboard.prototype.destroy = function(callback, errorback, always){};
return Dashboard;
});
51
6.3
Dashboard Structure
The Dashboard Data structure represents the rendered dashboard object manipulated by the dashboard function.
Even though it is named "data," it does not contain any data in the dashboard or reports, but rather the data
about the dashboard. For example, the Dashboard Data structure contains information about the items in the
dashboard, called dashlets.
{
"title": "Dashboard Data",
"description": "A JSON Schema describing a Dashboard Data",
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"parameters": {
"type": "array",
"description": "Dashboard parameters",
"items": {
"type": "object",
"description": "Dashboard parameter properties"
}
}
}
}
6.4
Rendering a Dashboard
To run a dashboard on the server and render it in Visualize.js, create a dashboard object and set its properties.
Like rendering a report, the resource property determine which report to run, and the container property
determines where it appears on your page.
var dashboard = v.dashboard({
resource: "/public/test_dashboard",
container: "#container",
success: function() { console.log("dashboard rendered"); },
error: function(e) { alert(e); }
});
The following code example shows how to define a dashboard ahead of time, then render it at a later time.
var dashboard = v.dashboard({
resource: "/public/test_dashboard",
runImmediately: false
});
dashboard
.run()
.done(function() {
this
.container("#container")
.render()
.done(function() { console.log("dashboard rendered"); })
.fail(function(e) { alert(e); });
})
.fail(function(e) { alert(e); });
52
6.5
Refreshing a Dashboard
You can order the refresh or re-render of the dashboard , as well as cancel the refresh if necessary, for example if
it takes too long.
var dashboard = v.dashboard({
resource: "/public/test_dashboard",
container: "#container",
runImmediately: false
});
dashboard.run().done(function() {
setTimeout(function() {
var dfd = dashboard.refresh();
// cancel refresh if it's still running after 2 seconds
setTimeout(function() {
if (dfd.state() === "pending") {
dashboard.cancel();
}
}, 2000);
}, 10000);
});
6.6
Then you read their values, modify them, and set new values. The dashboard then renders with the new input
parameter values:
var dashboard = v.dashboard({
resource: "/public/test_dashboard",
container: "#container",
params: {
Country: ["USA", "Mexico", "Canada"]
},
error: function(e) { alert(e); }
});
dashboard.params(); // returns { Country: ["USA", "Mexico", "Canada"] }
......
dashboard.params({ month: ["2"] }).run();
dashboard.params(); // returns { month: ["2"] }
53
In the following example, a button resets the paramters to their default values by sending a null parameter set.
First the HTML to define the container and the button:
<script src="http://localhost:8080/jasperserver-pro/client/visualize.js"></script>
<button>Reset params</button>
<br/><br/>
<div id="container"></div>
In another example, the script initializes the paramters and the HTML displays a button when they are ready to
be applied:
<script src="http://localhost:8080/jasperserver-pro/client/visualize.js"></script>
<br/>
<button disabled>Apply params</button>
<br/><br/>
<div id="container"></div>
And then the JavaScript to initialize the parameters and enable the button for the user:
function handleError(e) {
alert(e);
}
visualize({
54
auth: {
name: "superuser",
password: "superuser"
}
}, function (v) {
var initialParams = {
Country: ["USA", "Canada"]
};
var dashboard = v.dashboard({
resource: "/public/Samples/Dashboards/3.2_Inventory_Metrics",
container: "#container",
error: handleError,
params: initialParams,
success: function() {
$("button").prop("disabled", false);
buildParamsInput();
}
});
function buildParamsInput() {
var params = dashboard.data().parameters;
for (var i = params.length-1; i >= 0; i--) {
var $el = $("<div>" + params[i].id + ": <input type='text' data-paramId='" + params[i].id
+ "'/></div>");
$("body").prepend($el);
$el.find("input").val(dashboard.params()[params[i].id]);
}
}
$("button").on("click", function() {
var params = {};
$("[data-paramId]").each(function() {
params[$(this).attr("data-paramId")] = $(this).val().indexOf("[") > -1 ? JSON.parse
($(this).val()) : [$(this).val()];
});
$("button").prop("disabled", true);
dashboard.params(params).run()
.fail(handleError)
.always(function() { $("button").prop("disabled", false); });
});
});
You can create any number of user interfaces, database lookups, or your own calculations to provide the values
of parameters. Your parameters could be based on 3rd party API calls that get triggered from other parts of the
page or other pages in your app. When your dashboards can respond to dynamic events, they become truly
embedded and much more relevant to the user.
55
6.7
Reference The reference link indicates an external source that is identified by a normal URL. The only
expression required is the hyperlink reference expression. It's possible to specify additional parameters for
this hyperlink type.
LocalAnchor To point to a local anchor means to create a link between two locations into the same
document. It can be used, for example, to link the titles of a summary to the chapters to which they refer. To
define the local anchor, it is necessary to specify a hyperlink anchor expression, which will have to produce
a valid anchor name. It's possible to specify additional parameters for this hyperlink type.
LocalPage If instead of pointing to an anchor you want to point to a specific current report page, you
need to create a LocalPage link. In this case, it is necessary to specify the page number you are pointing to
by means of a hyperlink page expression (the expression has to return an Integer object). It's possible to
specify additional parameters for this hyperlink type.
RemoteAnchor If you want to point to a particular anchor that resides in an external document, you use
the RemoteAnchor link. In this case, the URL of the external file pointed to will have to be specified in the
Hyperlink Reference Expression field, and the name of the anchor will have to be specified in the
Hyperlink Anchor Expression field. It's possible to specify additional parameters for this hyperlink type.
RemotePage This link allows you to point to a particular page of an external document. Similarly, in this
case the URL of the external file pointed to, will have to be specified in the Hyperlink Reference
Expression field, and the page number will have to be specified by means of the hyperlink page expression.
Some export formats have no support for hypertext links. It's possible to specify additional parameters for
this hyperlink type.
ReportExecution This type of hyperlink is used to implement JasperServers drill-down feature. Page and
anchor can be specified for the hyperlink type as well as additional special parameters such as _report, _
anchor, _page, _output.
AdHocExecution This type of hyperlink represents an information about clicked point on chart reports
generated from AdHoc Charts. It exposes names of measures and values of dimensions as parameters.
Custom Hyperlink Type A type of hyperlink that you can define entirely.
Self This is the default setting. It opens the link in the current window.
Blank Opens the target in a new window. Used for output formats such as HTML and PDF
Top Opens the target in the current window but outside any frames. Used for output formats such as
HTML and PDF.
Parent Opens the target in the parent window (if available). Used for output formats such as HTML and
PDF.
Frame name Always opens the target in the specified frame.
The following table shows the new default action for each combination of link and target:
56
Type \ Targets
Self
Blank
Top
Parent
Reference
Referenced URL is
opened in an iframe
on top of the report.
Referenced url is
opened in new
tab.
Referenced url is
opened in same
window.
Referenced url is
opened in parent
frame for reports
generated from
AdHoc Charts.
Referenced report is
opened in same
place through Viz.js (if
hyperlink points to the
same report, it's just
gets updated with
params/page/anchor).
Referenced report
is opened in new
tab.
Referenced report
is opened in top
frame (same
window).
Referenced report
is opened in
parent frame.
Anchor is opened in
same place through
Viz.js.
Referenced report
anchor is opened
in new browser
tab.
Referenced report
anchor is opened
in top frame
(same window).
Referenced report
anchor is opened
in parent frame.
Page is opened in
same place through
Viz.js.
Referenced report
page is opened in
new browser tab.
Referenced report
page is opened in
top frame (same
window).
Referenced report
page is opened in
parent frame.
Referenced report
anchor is opened
in new browser
tab.
Referenced report
anchor is opened
in top frame
(same window).
Referenced report
anchor is opened
in parent frame.
Referenced report
page is opened in
new browser tab.
Referenced report
page is opened in
top frame (same
window).
Referenced report
page is opened in
parent frame.
(points to an
external resource)
ReportExecution
(points to
JasperReports
report)
LocalAnchor
(points to an
anchor in current
report)
LocalPage
(points to a page in
current report)
RemoteAnchor
(points to an
anchor in remote
document)
RemotePage
(points to a page in
remote document)
AdHocExecution
The hyperlink provides parameters, which are exposed to Filter Manager for additional
wiring (beyond the scope of this document).
The following code samples demonstrate the default handling of hyperlinks and the effect of defining overrides
that remove the default handling. First the HTML for some buttons:
<script src="http://localhost:8080/jasperserver-pro/client/visualize.js"></script>
<button id="btn1">Extend default hyperlink behavior</button>
<button id="btn2">Disable hyperlink click events</button>
<div id="container"></div>
57
visualize({
auth: {
name: "jasperadmin",
password: "jasperadmin",
organization: "organization_1"
}
}, function (v) {
var dashboard = v.dashboard({
resource: "/public/Dashboard_with_different_hyperlinks_with_self_target",
container: "#container",
error: function(e) {
alert(e);
}
});
document.querySelector("#btn1").addEventListener("click", function() {
dashboard.linkOptions({
events: {
click: function(ev, link, defaultHandler) {
alert("before default handler");
defaultHandler();
alert("after default handler");
}
}
}).run();
});
document.querySelector("#btn2").addEventListener("click", function() {
dashboard.linkOptions({
events: {
click: function(ev, link, defaultHandler) {
alert("default handler will not be called");
}
}
}).run();
});
});
However, if your dashboards are designed for custom drill-down, you can still define custom link handling so
your users can access more reports and more data. Be sure to modify your code to handle all three function
parameters for function(ev, link, default), as shown in this updated code sample:
var dashboard = v.dashboard({
resource: "/public/test_dashboard",
container: "#container",
linkOptions: {
beforeRender: function (linkToElemPairs) {
linkToElemPairs.forEach(showCursor);
},
events: {
"click": function(ev, link, default){
if (link.type == "ReportExecution") {
if ("monthNumber" in link.parameters) {
v("#drill-down").report({
resource: link.parameters._report,
params: {
58
monthNumber: [link.parameters.monthNumber]
}
});
}
}
}
}
}
});
function showCursor(pair){
var el = pair.element;
el.style.cursor = "pointer";
}
6.8
Closing a Dashboard
When you want to reuse a container for other contents and free the dashboard resources, use the destroy
function to close it.
var dashboard = v.dashboard({
resource: "/public/test_dashboard",
container: "#container"
});
dashboard.destroy();
59
60
CHAPTER 7
This chapter lists the errors that commonly occur and describes how to handle them with Visualize.js.
This chapter contains the following sections:
7.1
Error Properties
Common Errors
Catching Initialization and Authentication Errors
Catching Search Errors
Validating Search Properties
Catching Report Errors
Catching Input Control Errors
Validating Input Controls
Error Properties
The properties structure for Generic Errors is defined as follows:
{
"title": "Generic Errors",
"description": "A JSON Schema describing Visualize Generic Errors",
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"errorCode": {
"type": "string"
},
"message": {
"type": "string"
},
"parameters":{
"type": "array"
}
},
"required": ["errorCode", "message"]
}
61
7.2
Common Errors
The following table lists common errors, their message, and their cause.
7.3
Error
Message - Description
unexpected.error
schema.validation.error
unsupported.
configuration.error
authentication.error
container.not.found.error
Container was not found in DOM - The specified container was not found
in the DOM:error.
report.execution.failed
report.execution.cancelled
report.export.failed
licence.not.found
JRS missing appropriate licence - The server's license was not found.
licence.expired
resource.not.found
Resource not found in Repository - Either the resource does not exist in
the repository or the user doesn't have permissions to read it.
export.pages.out.range
Requested pages {0} out of range - The user requested pages which do
not exist in the current export.
input.controls.
validation.error
62
During intitialization and authentication, you can handle errors in the third parameter named errorback (an
error callback). Your application would then have this structure:
visualize({
auth : { ...
}
}, function(){
// your application logic
}, function(err){
// handle all initialization and authentication errors here
})
7.4
Another way to handle search errors is to specify a function as the third parameter of run. This function is an
always handler that run every time when operation ends.
new ResourcesSearch({
server:"http://localhost:8080/jasperserver-pro",
folderUri: "/public",
recursive: false
})).run(usefulFunction, errorHandler, function(resultOrError){
alert(resultOrError);
}))
7.5
63
}));
var error = call.validate();
if (!error){
// valid
} else {
// invalid, read details from error
}
7.6
7.7
64
.fail(function(err){
// handle errors here
});
)
7.8
65
66
CHAPTER 8
Depending on the size of your data, the report function can run for several seconds or minutes, just like reports
in the JasperReports Server UI. You can listen for events that give the status of running reports and let you
display pages sooner.
This chapter contains the following sections:
8.1
67
8.2
8.3
8.4
68
visualize({
auth: { ...
}
}, function (v) {
// enable report chooser
$(':disabled').prop('disabled', false);
//render report from provided resource
startReport();
$("#selected_resource").change(startReport);
function startReport () {
// clean container
$("#container").html("");
// render report from another resource
v("#container").report({
resource: $("#selected_resource").val(),
events:{
beforeRender: function(el){
// find all spans
$(el).find(".jrPage td span")
.each(function(i, e){
// make them red
$(e).css("color","red")
.attr("data-my-attr", "test");
});
console.log($(el).find(".jrPage").html());
}
}
});
};
});
The HTML page that displays the report uses a static list of reports in a drop-down selector, but otherwise needs
only a container element. This is similar to the basic report example in Rendering a Report on page32,
except that the JavaScript above will change the report before it is displayed.
<script src="http://code.jquery.com/jquery-2.1.0.js"></script>
<!-- Provide the URL to visualize.js -->
<script src="http://bi.example.com:8080/jasperserver-pro/client/visualize.js"></script>
<select id="selected_resource" disabled="true" name="report">
<option value="/public/Samples/Reports/1._Geographic_Results_by_Segment_Report">Geographic Results
by Segment</option>
<option value="/public/Samples/Reports/2_Sales_Mix_by_Demographic_Report">Sales Mix by
Demographic</option>
<option value="/public/Samples/Reports/3_Store_Segment_Performance_Report">Store Segment
Performance</option>
<option value="/public/Samples/Reports/04._Product_Results_by_Store_Type_Report">Product Results
by Store Type</option>
</select>
<!-- Provide a container to render your visualization -->
<div id="container"></div>
69
70
CHAPTER 9
Both reports and dashboards include hyperlinks (URLs) that link to websites or other reports. Visualize.js gives
you access to the links so that you can customize them or open them differently. For links generated in the
report, you can customize both the appearance and the container where they are displayed.
This chapter contains the following sections:
9.1
Structure of Hyperlinks
Customizing Links
Drill-Down in Separate Containers
Accessing Data In Links
Structure of Hyperlinks
The following JSONschema describes all the parameters on links, although not all are present in all cases.
{
"title": "JR Hyperlink",
"description": "A JSON Schema describing JR hyperlink",
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties":{
"id": {
"type": "string",
"description": "Hyperlink id, reflected in corresponding attribute in DOM. Is not used for
AdHocExecution hyperlink type."
},
"type": {
"type": "string",
"description": "Hyperlink type. Default types are LocalPage, LocalAnchor, RemotePage,
RemoteAnchor, Reference, ReportExecution, AdHocExecution. Custom hyperlink types are possible"
},
"target": {
"type": "string",
"description": "Hyperlink target. Default targets are Self, Blank, Top, Parent. Custom
hyperlink targets are possible"
},
"tooltip": {
71
"type": "string",
"description": "Hyperlink tooltip"
},
"href": {
"type" : "string",
"description": "Hyperlink reference. Is an empty string for LocalPage, LocalAnchor and
ReportExecution hyperlink types"
},
"parameters": {
"type": "object",
"description": "Hyperlink parameters. Any additional parameters for hyperlink"
},
"resource": {
"type": "string",
"description": "Repository resource URI of resource mentioned in hyperlink. For LocalPage
and LocalAnchor points to current report, for ReportExecution - to _report parameter"
},
"pages": {
"type": ["integer", "string"],
"description": "Page to which hyperlink points to. Is actual for LocalPage, RemotePage and
ReportExecution hyperlink types"
},
"anchor": {
"type": "string",
"description": "Anchor to which hyperlink points to. Is actual for LocalAnchor,
RemoteAnchor and ReportExecution hyperlink types"
}
},
"required": ["type", "id"]
}
9.2
Customizing Links
You can customize the appearance of link elements in a generated report in two ways:
The linkOptionsexposes the beforeRender event to which you can add a listener that has access to the
links in the document as element pairs.
The normal click event lets your add a listener that has access to a link when it is clicked.
visualize({
auth: {
name: "jasperadmin",
password: "jasperadmin",
organization: "organization_1"
}
},function (v) {
v("#container1").report({
resource: "/AdditionalResourcesForTesting/Drill_Reports_with_Controls/main_report",
linkOptions: {
beforeRender: function (linkToElemPairs) {
linkToElemPairs.forEach(function (pair) {
var el = pair.element;
el.style.backgroundColor = "red";
});
},
72
events: {
"click": function(ev, link){
if (confirm("Change color of link id " + link.id + " to green?")){
ev.currentTarget.style.backgroundColor = "green";
ev.target.style.color = "#FF0";
}
}
}
},
error: function (err) {
alert(err.message);
}
});
});
9.3
73
function showCursor(pair){
var el = pair.element;
el.style.cursor = "pointer";
}
});
Associated HTML:
<script src="http://underscorejs.org/underscore.js"></script>
<script src="http://code.jquery.com/jquery-2.1.0.js"></script>
<!-- Provide the URL to visualize.js -->
<script src="http://bi.example.com:8080/jasperserver-pro/client/visualize.js"></script>
<!-- Provide a container for the main report and one for the drill-down -->
<div>
<div style="width:830px;" id="main"></div>
<div style="width:500px;" id="drill-down"></div>
</div>
Associated CSS:
#main{
float: left;
}
#drill-down{
float: left;
}
9.4
74
function refreshSelect(data){
console.log(data);
var options = data.links.reduce(function(memo, link){
console.log(link);
return memo + ""+link.tooltip+"";
},"");
$select.html(options);
}
$("#previousPage").click(function() {
var currentPage = report.pages() || 1;
goToPage(--currentPage);
});
$("#nextPage").click(function() {
var currentPage = report.pages() || 1;
goToPage(++currentPage);
});
function goToPage(numder){
report
.pages(numder)
.run()
.done(refreshSelect)
.fail(showError);
}
function showError(err){
alert(err.message);
}
});
Associated HTML:
<script src="http://code.jquery.com/jquery-2.1.0.js"></script>
<!-- Provide the URL to visualize.js -->
<script src="http://bi.example.com:8080/jasperserver-pro/client/visualize.js"></script>
<select id="selectCity"></select>
<button id="previousPage">Previous Page</button>
<button id="nextPage">Next Page</button>
<!-- Provide a container for the main report -->
<div>
<div style="width:20px;"></div>
<div style="width:500px;" id="main"></div>
</div>
Associated CSS:
#main{
float: left;
}
75
76
77
enabled: true
}
});
...
var components = report.data().components;
Each component of the JIVE UI has an id, but it may change from execution to execution. To refer to
components of the UI, create your report in JRXML and use the net.sf.jasperreports.components.name
property to name each component you want to reference, such as a column in a table. Then you can reference
the object by this name, for example "sales", and use the updateComponent function.
report.updateComponent("sales", {
sort : {
order : "asc"
}
});
Or:
report.updateComponent({
name: "sales",
sort : {
order : "asc"
}
});
We can also get an object that represents the named component of the JIVE UI:
var salesColumn = report
.data()
.components
.filter(function(c){ return c.name === "sales"})
.pop();
The following example shows how to create buttons whose click event modify the report through the JIVE UI:
visualize({
auth: { ...
}
}, function (v) {
//render report from provided resource
var report = v.report({
resource: "/public/Samples/Reports/RevenueDetailReport",
container: "#container",
success: printComponentsNames,
error: handleError
});
$("#resetAll").on("click", function(){
78
report.undoAll();
});
$("#changeFemale").on("click", function () {
//component's name generated by default from field name
report.updateComponent("femalesales", {
sort: {
order: "asc"
},
filter: {
operator: "greater_or_equal",
value: 15000
}
}).fail(handleError);
});
$("#changeDep").on("click", function () {
//custom compoent's name
report.updateComponent("my_dep", {
sort: {
order: "desc"
}
}).fail(handleError);
});
$("#changeChart").on("click", function () {
//custom compoent's name
report.updateComponent("revenue", {
chartType: "Pie"
}).fail(handleError);
});
//show error
function handleError(err){
alert(err.message);
}
function printComponentsNames(data){
data.components.forEach(function(c){
console.log("Component Name: " + c.name, "Component Lable: "+ c.label);
});
}
});
The associated HTML has buttons that will invoke the JavaScript actions on the JIVE UI:
<!-- Provide the URL to visualize.js -->
<script src="http://bi.example.com:8080/jasperserver-pro/client/visualize.js"></script>
<button id="resetAll">Reset All</button>
<button id="changeFemale">Filter And Sort Female</button>
<button id="changeDep">Sort Departments</button>
<button id="changeChart">Show in Pie</button>
<!-- Provide a container for the report -->
<div id="container"></div>
79
Or:
report
.updateComponent("salesChart", {
chartType: "Bar"
})
.done(function(){
alert("Chart type changed!");
})
.fail(function(err){
alert(err.message);
});
The following example creates a drop-down menu that lets users change the chart type. You could also set the
chart type programmatically, according to other states in your client.
This code also relies on the report.chart.types interface described in Discovering Available Charts and
Formats on page40.
visualize({
auth: { ...
}
}, function (v) {
//persisted chart name
var chartName = "geo_by_seg",
$select = buildControl("Chart types: ", v.report.chart.types),
report = v.report({
resource: "/public/Reports/1._Geographic_Results_by_Segment_Report",
container: "#container",
success: selectDefaultChartType
});
$select.on("change", function () {
80
report.updateComponent(chartName, {
chartType: $(this).val()
})
.done(function (component) {
chartComponent = component;
})
.fail(function (error) {
alert(error);
});
});
function selectDefaultChartType(data) {
var component = data.components
.filter(function (c) {
return c.name === chartName;
})
.pop();
if (component) {
$select.find("option[value='" + component.chartType + "']")
.attr("selected", "selected");
}
}
function buildControl(name, options) {
function buildOptions(options) {
var template = "<option>{value}</option>";
return options.reduce(function (memo, option) {
return memo + template.replace("{value}", option);
}, "")
}
console.log(options);
if (!options.length) {
console.log(options);
}
var template = "<label>{label}</label><select>{options}</select><br>",
content = template.replace("{label}", name)
.replace("{options}", buildOptions(options));
var $control = $(content);
$control.insertBefore($("#container"));
return $control;
}
});
As shown in the following HTML, the control for the chart type is created dynamically by the JavaScript:
<script src="http://code.jquery.com/jquery-2.1.0.js"></script>
<!-- Provide the URL to visualize.js -->
<script src="http://bi.example.com:8080/jasperserver-pro/client/visualize.js"></script>
<!-- Provide a container for the report -->
<div id="container"></div>
81
id="disableZoom">disable zoom</button>
id="zoomX">set zoom to 'x' type</button>
id="zoomY">set zoom to 'y' type</button>
id="zoomXY">set zoom to 'xy' type</button>
id="resetZoom">reset zoom to initial state</button>
<div id="container"></div>
Here are the API calls to set the various chart properties:
visualize({
auth: {
name: "jasperadmin",
password: "jasperadmin",
organization: "organization_1"
}
}, function (v) {
var report = v.report({
resource: "/public/Samples/Reports/01._Geographic_Results_by_Segment_Report",
container: "#container",
error: function(e) {
alert(e);
}
});
function changeChartProperty(prop, value) {
var chartProps = report.chart();
if (typeof value === "undefined") {
delete chartProps[prop];
} else {
chartProps[prop] = value;
}
report.chart(chartProps).run().fail(function(e) { alert(e); });
}
$("#disableAnimation").on("click", function() {
82
changeChartProperty("animation", false);
});
$("#enableAnimation").on("click", function() {
changeChartProperty("animation", true);
});
$("#resetAnimation").on("click", function() {
changeChartProperty("animation");
});
$("#disableZoom").on("click", function() {
changeChartProperty("zoom", false);
});
$("#zoomX").on("click", function() {
changeChartProperty("zoom", "x");
});
$("#zoomY").on("click", function() {
changeChartProperty("zoom", "y");
});
$("#zoomXY").on("click", function() {
changeChartProperty("zoom", "xy");
});
$("#resetZoom").on("click", function() {
changeChartProperty("zoom");
});
});
83
84
return chartTypeSelect;
}
Associated HTML:
<script src="http://code.jquery.com/jquery-2.1.0.js"></script>
<!-- Provide the URL to visualize.js -->
<script src="http://bi.example.com:8080/jasperserver-pro/client/visualize.js"></script>
<select id="chartType"></select>
<button id="undo" disabled="disabled">Undo</button>
<button id="redo" disabled="disabled">Redo</button>
<button id="undoAll" disabled="disabled">Undo All</button>
<!-- Provide a container for the report -->
<div id="container"></div>
85
function showError(err) {
alert(err);
}
});
Associated HTML:
<script src="http://code.jquery.com/jquery-2.1.0.js"></script>
<script src="http://underscorejs.org/underscore-min.js"></script>
<!-- Provide the URL to visualize.js -->
<script src="http://bi.example.com:8080/jasperserver-pro/client/visualize.js"></script>
<button id="sortAsc">Sort NAME column ASCENDING</button>
<button id="sortDesc">Sort NAME column DESCENDING</button>
<button id="sortNone">Reset NAME column</button>
<!-- Provide a container for the report -->
<div id="container"></div>
86
$("#setBooleanTrue").on("click", function() {
report.updateComponent("column_boolean", {
filter: {
operator: "equal",
value: true
}
}).fail(handleError);
});
$("#resetBoolean").on("click", function() {
report.updateComponent("column_boolean", {
filter: {}
}).fail(handleError);
});
$("#setStringContains").on("click", function() {
report.updateComponent("column_string", {
filter: {
operator: "contain",
value: $("#stringContains").val()
}
}).fail(handleError);
});
$("#resetString").on("click", function() {
report.updateComponent("column_string", {
filter: {}
}).fail(handleError);
});
$("#setNumericGreater").on("click", function() {
report.updateComponent("column_double", {
filter: {
operator: "greater",
value: parseFloat($("#numericGreater").val(), 10)
}
}).fail(handleError);
});
$("#resetNumeric").on("click", function() {
report.updateComponent("column_double", {
filter: {}
}).fail(handleError);
});
$("#setTimeBefore").on("click", function() {
report.updateComponent("column_time", {
filter: {
operator: "before",
value: $("#timeBefore").val()
}
}).fail(handleError);
});
$("#resetTime").on("click", function() {
report.updateComponent("column_time", {
filter: {}
87
}).fail(handleError);
});
});
function handleError(err) {
console.log(err);
alert(err);
}
Associated HTML:
<script src="http://code.jquery.com/jquery-2.1.0.js"></script>
<script src="http://underscorejs.org/underscore-min.js"></script>
<!-- Provide the URL to visualize.js -->
<script src="http://bi.example.com:8080/jasperserver-pro/client/visualize.js"></script>
88
report = v.report({
resource: "/public/viz/report_with_different_column_types",
container: "#container",
events: {
reportCompleted: function (status, error) {
if (status === "ready") {
columns = _.filter(report.data().components, function (component) {
return component.componentType == "tableColumn";
});
var column4 = columns[4];
$("#label").val(column4.label);
$("#headingFormatAlign").val(column4.headingFormat.align);
$("#headingFormatBgColor").val(column4.headingFormat.backgroundColor);
$("#headingFormatFontSize").val(column4.headingFormat.font.size);
$("#headingFormatFontColor").val(column4.headingFormat.font.color);
$("#headingFormatFontName").val(column4.headingFormat.font.name);
if (column4.headingFormat.font.bold) {
$("#headingFormatFontBold").attr("checked", "checked");
} else {
$("#headingFormatFontBold").removeAttr("checked");
}
if (column4.headingFormat.font.italic) {
$("#headingFormatFontItalic").attr("checked", "checked");
} else {
$("#headingFormatFontItalic").removeAttr("checked");
}
if (column4.headingFormat.font.underline) {
$("#headingFormatFontUnderline").attr("checked", "checked");
} else {
$("#headingFormatFontUnderline").removeAttr("checked");
}
$("#detailsRowFormatAlign").val(column4.detailsRowFormat.align);
$("#detailsRowFormatBgColor").val(column4.detailsRowFormat.backgroundColor);
$("#detailsRowFormatFontSize").val(column4.detailsRowFormat.font.size);
$("#detailsRowFormatFontColor").val(column4.detailsRowFormat.font.color);
$("#detailsRowFormatFontName").val(column4.detailsRowFormat.font.name);
if (column4.detailsRowFormat.font.bold) {
$("#detailsRowFormatFontBold").attr("checked", "checked");
} else {
$("#detailsRowFormatFontBold").removeAttr("checked");
}
if (column4.detailsRowFormat.font.italic) {
$("#detailsRowFormatFontItalic").attr("checked", "checked");
} else {
$("#detailsRowFormatFontItalic").removeAttr("checked");
}
if (column4.detailsRowFormat.font.underline) {
89
$("#detailsRowFormatFontUnderline").attr("checked", "checked");
} else {
$("#detailsRowFormatFontUnderline").removeAttr("checked");
}
$("#detailsRowFormatPatternNegativeFormat").val(
column4.detailsRowFormat.pattern.negativeFormat);
$("#detailsRowFormatPatternPrecision").val(
column4.detailsRowFormat.pattern.precision);
$("#detailsRowFormatPatternCurrency").val(
column4.detailsRowFormat.pattern.currency || "");
if (column4.detailsRowFormat.pattern.percentage) {
$("#detailsRowFormatPatternPercentage").attr("checked", "checked");
} else {
$("#detailsRowFormatPatternPercentage").removeAttr("checked");
}
if (column4.detailsRowFormat.pattern.grouping) {
$("#detailsRowFormatPatternGrouping").attr("checked", "checked");
} else {
$("#detailsRowFormatPatternGrouping").removeAttr("checked");
}
}
}
},
error: function (err) {
alert(err);
}
});
$("#changeHeadingFormat").on("click", function () {
report.updateComponent(columns[4].id, {
headingFormat: {
align: $("#headingFormatAlign").val(),
backgroundColor: $("#headingFormatBgColor").val(),
font: {
size: parseFloat($("#headingFormatFontSize").val()),
color: $("#headingFormatFontColor").val(),
underline: $("#headingFormatFontUnderline").is(":checked"),
bold: $("#headingFormatFontBold").is(":checked"),
italic: $("#headingFormatFontItalic").is(":checked"),
name: $("#headingFormatFontName").val()
}
}
}).fail(function (e) {
alert(e);
});
});
$("#changeDetailsRowFormat").on("click", function () {
report.updateComponent(columns[4].id, {
detailsRowFormat: {
align: $("#detailsRowFormatAlign").val(),
backgroundColor: $("#detailsRowFormatBgColor").val(),
90
The associated HTML has static controls for selecting all the formatting options that the script above can
modify in the report.
<script src="http://code.jquery.com/jquery-2.1.0.js"></script>
<script src="http://underscorejs.org/underscore-min.js"></script>
<!-- Provide the URL to visualize.js -->
<script src="http://bi.example.com:8080/jasperserver-pro/client/visualize.js"></script>
<div style="float: left;">
<h3>Heading format for 5th column</h3>
Align: <select id="headingFormatAlign">
<option value="left">left</option>
<option value="center">center</option>
<option value="right">right</option></select>
<br/>
Background color: <input type="text" id="headingFormatBgColor" value=""/>
<br/>
Font size: <input type="text" id="headingFormatFontSize" value=""/>
<br/>
Font color: <input type="text" id="headingFormatFontColor" value=""/>
<br/>
Font name: <input type="text" id="headingFormatFontName" value=""/>
<br/>
Bold: <input type="checkbox" id="headingFormatFontBold" value="true"/>
<br/>
Italic: <input type="checkbox" id="headingFormatFontItalic" value="true"/>
<br/>
Underline: <input type="checkbox" id="headingFormatFontUnderline" value="true"/>
<br/><br/>
<button id="changeHeadingFormat">Change heading format</button>
</div>
<div style="float: left;">
<h3>Details row format for 5th column</h3>
Align: <select id="detailsRowFormatAlign">
<option value="left">left</option>
<option value="center">center</option>
<option value="right">right</option></select>
<br/>
Background color: <input type="text" id="detailsRowFormatBgColor" value=""/>
<br/>
Font size: <input type="text" id="detailsRowFormatFontSize" value=""/>
<br/>
Font color: <input type="text" id="detailsRowFormatFontColor" value=""/>
<br/>
Font name: <input type="text" id="detailsRowFormatFontName" value=""/>
<br/>
Bold: <input type="checkbox" id="detailsRowFormatFontBold" value="true"/>
<br/>
Italic: <input type="checkbox" id="detailsRowFormatFontItalic" value="true"/>
<br/>
Underline: <input type="checkbox" id="detailsRowFormatFontUnderline" value="true"/>
<br/><br/>
<b>Number pattern:</b>
91
<br/>
Negative format: <input type="text" id="detailsRowFormatPatternNegativeFormat"/>
<br/>
Precision: <input type="text" id="detailsRowFormatPatternPrecision"/>
<br/>
Currency: <select id="detailsRowFormatPatternCurrency">
<option value="">----</option>
<option value="USD">USD</option>
<option value="EUR">EUR</option>
<option value="GBP">GBP</option>
<option value="YEN">YEN</option>
<option value="LOCALE_SPECIFIC">LOCALE_SPECIFIC</option>
</select>
<br/>
Thousands grouping: <input type="checkbox" id="detailsRowFormatPatternGrouping" value="true"/>
<br/>
Percentage: <input type="checkbox" id="detailsRowFormatPatternPercentage" value="true"/>
<br/><br/>
<button id="changeDetailsRowFormat">Change details row format</button>
</div>
<div style="float: left;">
<h3>Change label of 5th column</h3>
<br/>
Label <input type="text" id="label"/>
<br/>
<button id="changeLabel">Change label</button>
</div>
<div style="clear: both;"></div>
<!-- Provide a container for the report -->
<div id="container"></div>
92
report.updateComponent(salesColumnName, {
conditions: [
{
operator: "greater",
value: 10,
backgroundColor: null,
font: {
color: "FF0000",
bold: true,
underline: true,
italic: true
}
},
{
operator: "between",
value: [5, 9],
backgroundColor: "00FF00",
font: {
color: "0000FF"
}
}
]
})
.then(printConditions)
.fail(showError);
});
function printConditions(component){
console.log("Conditions: "+ component.conditions);
}
function showError(err) {
alert(err);
}
});
This example has a single button that allows the user to apply the conditional formatting when the report is
loaded:
<script src="http://code.jquery.com/jquery-2.1.0.js"></script>
<script src="http://underscorejs.org/underscore-min.js"></script>
<!-- Provide the URL to visualize.js -->
<script src="http://bi.example.com:8080/jasperserver-pro/client/visualize.js"></script>
<button id="changeConditions">Change conditions for numeric column</button>
<!-- Provide a container for the report -->
<div id="container"></div>
93
visualize({
auth: {
name: "superuser",
password: "superuser"
}
}, function (v) {
var column2,
report = v.report({
resource: "/public/MyReports/crosstabReport",
container: "#container",
events: {
reportCompleted: function (status, error) {
if (status === "ready") {
var columns = _.filter(report.data().components, function (component) {
return component.componentType == "crosstabDataColumn";
});
column2 = columns[1];
console.log(columns);
}
}
},
error: function (err) {
alert(err);
}
});
$("#sortAsc").on("click", function () {
report.updateComponent(column2.id, {
sort: {
order: "asc"
}
}).fail(function (e) {
alert(e);
});
});
$("#sortDesc").on("click", function () {
report.updateComponent(column2.id, {
sort: {
order: "desc"
}
}).fail(function (e) {
alert(e);
});
});
$("#sortNone").on("click", function () {
report.updateComponent(column2.id, {
sort: {}
}).fail(function (e) {
alert(e);
});
});
});
94
<script src="http://code.jquery.com/jquery-2.1.0.js"></script>
<script src="http://underscorejs.org/underscore-min.js"></script>
<!-- Provide the URL to visualize.js -->
<script src="http://bi.example.com:8080/jasperserver-pro/client/visualize.js"></script>
<button id="sortAsc">Sort 2nd column ascending</button>
<button id="sortDesc">Sort 2nd column descending</button>
<button id="sortNone">Do not sort on 2nd column</button>
<!-- Provide a container for the report -->
<div id="container"></div>
95
});
});
$("#sortNone").on("click", function () {
report.updateComponent(row.id, {
sort: {}
}).fail(function (e) {
alert(e);
});
});
});
Associated HTML:
<script src="http://bi.example.com:8080/jasperserver-pro/client/visualize.js"></script>
<p>JIVE UI is disabled on this Visualize.js report:</p>
<div id="reportContainer">Loading...</div>
96
97
},
error:handleError
});
}
//show error
function handleError(err){
alert(err.message);
}
});
The ScopeChecker is another JavaScript used in this example. It can either be a separate .js file or included in
your HTML file as shown in this example:
<!-- JavaScript for ScopeChecker -->
<script>
function ScopeChecker(scope) {
this.scope = scope;
}
ScopeChecker.prototype.getPropertiesCount = function() {
return this.getPropertiesNames().length;
};
ScopeChecker.prototype.getPropertiesNames = function() {
return Object.keys(this.scope);
};
ScopeChecker.prototype.compareProperties = function(scope1PropertiesNames, scope2PropertiesNames)
{
if (!scope1PropertiesNames) {
throw "Properties for scope 1 not specified";
}
if (!scope2PropertiesNames) {
scope2PropertiesNames = this.getPropertiesNames();
}
var comparisonResult = {
added: [],
removed: [],
madeUndefined: [],
pollution: []
};
var i, j;
for (i = 0; i < scope1PropertiesNames.length; i++) {
comparisonResult.removed.push(scope1PropertiesNames[i]);
for (j = 0; j < scope2PropertiesNames.length; j++) {
if (scope1PropertiesNames[i] === scope2PropertiesNames[j]) {
comparisonResult.removed.pop();
break;
}
}
}
for (i = 0; i < scope2PropertiesNames.length; i++) {
comparisonResult.added.push(scope2PropertiesNames[i]);
for (j = 0; j < scope1PropertiesNames.length; j++) {
if (scope2PropertiesNames[i] === scope1PropertiesNames[j]) {
98
comparisonResult.added.pop();
break;
}
99
100
"ColdFusion",
"Erlang",
"Fortran",
"Groovy",
"Haskell",
"Java",
"JavaScript",
"Lisp",
"Perl",
"PHP",
"Python",
"Ruby",
"Scala",
"Scheme"
];
$( "#tags" ).autocomplete({
source: availableTags
});
$("#datepicker-user").datepicker();
$("#datepicker-user2").datepicker();
$( "#tabs" ).tabs();
$("#loadV").click(loadV);
fillSheetList();
loadCSS();
$(window).on("keypress", function(e){
var char = e.charCode - 49;
if (char < 1 && char > 9) return;
var input = $("#sheetList > li > input")[char];
if (!input) return;
$(input).trigger( "click" )
});
$("#isolateDOM").change(function() {
$("#defaultJiveUi").attr({
"disabled": $(this).is(':checked') ? "disabled" : null,
"checked": false
});
});
}
function loadCSS() {
var CSSlibs = [
{ disable: true, href: serverUrls[urlUsed] + "/themes/reset.css" },
{ disable: true, href: "//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" },
{ disable: true, href: "//cdnjs.cloudflare.com/ajax/libs/normalize/3.0.1/normalize.min.css" },
{ disable: true, href: "//cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.css" },
{ disable: true, href: "http://yui.yahooapis.com/3.16.0/build/cssreset/cssreset-min.css" },
{ disable: true, href: "http://tantek.com/log/2004/undohtml.css" },
{ disable: true, href: "//cdnjs.cloudflare.com/ajax/libs/sanitize.css/2.0.0/sanitize.css" },
{ disable: false, href:
"http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/themes/vader/jquery-ui.css" }
];
var head = $("head"),
link;
101
102
103
function fillSheetList() {
var sheets = $("link");
var checkboxLI = '<li>#index: <input type="checkbox" id="#id" checked="checked"><label for="#id"
title="#title">#label</label></li>',
sheetPath = '',
sheetPathSplitted = '',
html = "";
$("#sheetList").html("");
for (var i = 0; i < sheets.length; i++) {
if (sheets[i].href === null) continue;
sheetPath = sheets[i].href;
sheetPathSplitted = sheetPath.split("/");
html = checkboxLI.replace(/#id/g, "sheetItem_" + i)
.replace(/#index/g, i+1)
.replace("#title", sheetPath)
.replace("#label", sheets[i].label || sheetPathSplitted[sheetPathSplitted.length - 1]);
$("#sheetList").append(html);
$("#sheetItem_" + i).change(function (e) {
var id = this.id.split("_")[1];
$("link")[id].disabled = !$(this).is(':checked');
});
$("#sheetItem_" + i)[0].checked = !$("link")[i].disabled;
}
}
The HTML for the CSS diagnostic tool contains a static list of reports to load. Add your own reports to this list.
<script type="text/javascript">
window.addEventListener("load", onLoad);
</script>
<div style="width:327px;float: left;border-right:1px solid #333;margin-right:2px">
<h4>Settings</h4>
<div>
<div id="containerLoadV">
<div id="serverUrlsDiv"></div>
<label for="confLocale">Locale: </label>
<input id="confLocale" value="en" />
<!-- options -->
<br/>
<input id="confOptimized" type="checkbox" />
<label for="confOptimized" >- use optimized javascript </label>
<br/>
<button id="loadV">Load visualize</button>
<br/>
</div>
<div id="loadReports" style="display:none;">
<div>Add report:</div>
<input id="defaultJiveUi" type="checkbox" checked="checked" />
104
105
icon only</button>
icon on the left</button>
two icons</button>
two icons and no text</button>
</div>
<div style="margin-left:330px;height:100%">
<div id="reportContainer"></div>
</div>
Associated CSS:
.qwe {
height: 100%;
}
#reportContainer {
height: 100%;
}
body, html {
height: 100%;
}
#containerLoadV.disabled {
color: #666;
}
/**
* Break something: modify the CSS here to something visibly wrong.
* Add more elements, classes, or IDs to see if they affect Visualize.js content.
*/
table {
font-size: 25px;
}
106
INDEX
A
a element (hyperlink) 71
accessType 20, 22
adhocDataView 19
alignment of cells 88
anchor element 71
Area 28
AreaSpline 28
auth property 13
authentication
error 62
handling errors 63
authentication.error 62
awsDataSource 19
B
Bar 28
beanDataSource 19
beforeRender event 68, 72
Bubble 28
C
cancel 28, 50-51
canceling reports 39
canRedo event 83
canUndo event 83
cascading input controls 46
cell
alignment 88
background color 88, 92
font 88
text color 88, 92
Central Authentication Service (CAS) 13
changeTotalPages event 68
chart type 80
chart types 40
chartComponent 28
chartType 28
click event 72
Column 28
ColumnLine 28
ColumnSpline 28
components 31
conditional formatting 92
container 7
container.not.found.error 62
CSS (Cascading Style Sheets) 99
customDataSource 19
D
dashboard 19
drill-down 58
hyperlinks 58
parameters 53
refreshing 53
rendering 52
dashboard structure 52
dashlets 52
dataType 19
defaultJiveUi 25, 49, 62, 96
destroy 30, 50-51
107
E
enum 19
errors 61
event
beforeRender 68, 72
canRedo 83
canUndo 83
changeTotalPages 68
click 72
pageFinal 68
reportCompleted 67, 88
events 28, 67
eventsMapper 28
Excel export 37
export 30
error 62
export formats 40
export.pages.out.range 62
exporting reports 37
external authentication 14
F
file 19
filtering table columns 86
folder 19
folderUri 19, 21-22
font 88
font size 88
forceTotalCount 20, 22
formatting table columns 88
H
href 32
hyperlink
accessing data 74
drill-down 73
108
modifying 71
I
input control
cascading 46
error 62
fetching 45
functions 44
handling errors 64
properties 43
structure 44
validate 65
widgets (UI) 45
input controls 43
input.controls.validation.error 62
inputControl 19
isolateDom 25, 49, 62
isolateDOM 99
J
jdbcDataSource 19
JIVE UI
conditional formatting 92
disabling 96
filtering tables 86
formatting tables 88
redo 83
sorting crosstabs 93, 95
sorting tables 85
undo 83
JIVE UI (interactivity) 77
jndiJdbcDataSource 19
JrsClient 8
JRXML 74
JSESSIONID cookie 17
L
label 44
licence.expired 62
licence.not.found 62
limit 19, 21
Line 28
linkOptions 25, 49, 72
links 31
linkTypeReferencelinkTypeReportExecution 32
listOfValues 19
Index
login
callback 15
external auth 14
plaintext 13
pre-authentication 13
SSO 13, 16
logout 14
callback 15
external auth 14
M
mandatory 44
masterDependencies 44
modifying chart type 80
mondrianConnection 19
mondrianXmlaDefinition 19
MultiAxisColumn 28
MultiAxisLine 28
MultiAxisSpline 28
N
net.sf.jasperreports.components.name 78
next page 35, 59
O
offset 19, 21
olapUnit 19
organization 13
P
pageFinal event 68
pages 25, 35-36, 49, 59
paginated 28
pagination
controls 35, 59
error 62
events 68
setting pages 35
parameters 32-33
dashboard 53
params 25, 49
password 13
PDF export 36
Pie 28
previous page 35, 59
properties
scope 97
Q
q 19, 21
query 19
R
range (pagination) 36
readOnly 44
recursive 19, 21-22
redo 30, 83
refresh 50-51
refreshing dashboard 53
refreshing reports 38
render 28, 50-51
rendering dashboards 52
report 73
canceling 39
conditional formatting 92
CSS 99
events 67
Excel 37
exporting 37
filtering tables 86
formatting tables 88
handling errors 64
hyperlinks 71
interactivity 77
JIVE 77
multiple 34
paginated 35, 59
PDF 36
refresh 38
rendering 32
setting pages 35
setting parameters 33
sorting crosstabs 93, 95
sorting tables 85
report properties 25, 49
report structure 31
report.execution.cancelled 62
report.execution.failed 62
report.export.failed 62
reportCompleted event 67
reportOptions 19
109
reportUnit 19
repository 22
error 62
resource 25, 49
resource.not.found 62
resourceLookups 22
ResourcesSearch 21-22
run 28, 50-51
S
Scatter 28
schema.validation.error 62
scope of properties 97
search
handling errors 63
properties 63
secureMondrianConnection 19
semanticLayerDataSource 19
server 19
session
expired 62
login 13
logout 14
showHiddenItems 20, 22
single-sign-on (SSO) 13
slaveDependencies 44
sortBy 20, 22
sorting crosstab columns 93
sorting crosstab rows 95
sorting table columns 85
SpiderArea 28
SpiderColumn 28
SpiderLine 28
spinner 39
Spline 28
StackedArea 28
StackedAreaSpline 28
StackedBar 28
StackedColumn 28
StackedColumnLine 28
StackedColumnSpline 28
StackedLine 28
StackedPercentArea 28
StackedPercentAreaSpline 28
StackedPercentBar 28
StackedPercentColumn 28
110
StackedPercentLine 28
StackedPercentSpline 28
StackedSpline 28
T
table column types 40
text color 88, 92
TimeSeriesArea 28
TimeSeriesAreaSpline 28
TimeSeriesLine 28
TimeSeriesSpline 28
timezone 13
tooltip 32
totalPages 31
type 19, 21, 44
types 23
U
undo 30, 83
undoAll 30, 77
unexpected.error 62
unsupported.configuration.error 62
updateComponent 28, 77-78
uri 44
username 13
V
validating input controls 65
validating search properties 63
validationRules 44
virtualDataSource 19
visible 44
visualize
configuration 16
CSS 99
error 62
scope 97
tools 97
usage 9
visualize.config 16
visualize.js
contents 8
parameters 8
requesting 7
Index
X
xmlaConnection 19
111
112