The report function runs reports on JasperReports Server and displays the result in a container that you provide.
This chapter contains the following sections:
• | 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.", "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": { "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" }, "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"] } } } |
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. * @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 report's component * @param {String} id - jive component id * @param {Object} properties - jive component's properties to 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.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; }); |
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, and components of the JIVE UI, as explained in Interacting With JIVE UI Components.
{ "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": { "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" } } } } } |
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 }); }); //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> |
Setting Report Parameters
To set or change the parameter values, update the params object of the report properties and invoke the run function again.
// update report with new parameters report .params({ "Country": ["USA"] }) .run(); ... // later in code console.log(report.params()); // console log output: {"Country": ["USA"] } |
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.
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.
Rendering Multiple Reports
visualize({ auth: { ... } }, function (v) { var reportsToLoad = [ "/public/Samples/Reports/AllAccounts", "/public/Samples/Reports/01._Geographic_Results_by_Segment_Report", "/public/Samples/Reports/Cascading_Report_2_Updated", "/public/Samples/Reports/07g.RevenueDetailReport" ]; $.each(reportsToLoad, function (index, uri) { var container = "#container" + (index + 1); v(container).report({ resource: uri, success: function () { console.log("loaded: " + (index + 1)); }, error: function (err) { alert(err.message); } }); }); }); |
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%; } |
Setting Report Pagination
To set or change the pages of the report that are displayed, update the pages object of the report properties and invoke the run function again.
report .pages(5) .run(); // re-render report with page 5 into the same container report .pages("2") // string is also allowed .run(); report .pages("4-6") // a range of numbers in a string is also possible .run(); |
Creating Pagination Controls (Next/Previous)
Again, the power of Visualize.js comes from these simple controls that you can access programmatically. You can create any sort of mechanism or user interface to select the page. In this example, the HTML has buttons that allow the user to choose the next or previous pages.
visualize({ auth: { ... } }, function (v) { var report = v.report({ resource: "/public/Samples/Reports/AllAccounts", container: "#container" }); $("#previousPage").click(function() { var currentPage = report.pages() || 1; report .pages(--currentPage) .run() .fail(function(err) { alert(err); }); }); $("#nextPage").click(function() { var currentPage = report.pages() || 1; report .pages(++currentPage) .run() .fail(function(err) { alert(err); }); }); }); |
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 id="previousPage">Previous Page</button><button id="nextPage">Next Page</button> <div id="container"></div> |
Creating Pagination Controls (Range)
visualize({ auth: { ... } }, function (v) { var report = v.report({ resource: "/public/Samples/Reports/AllAccounts", container: "#container" }); $("#pageRange").change(function() { report .pages($(this).val()) .run() .fail(function(err) { alert(err); }); }); }); |
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> |
Exporting From a Report
To export a report, invoke its export function and specify the outputFormat property. You MUST wait until the run action has completed before starting the export. The following export formats are supported:
"pdf", "xlsx", "xls", "rtf", "csv", "xml", "odt", "ods", "docx"
report.run(exportToPdf); function exportToPdf() { report .export({ outputFormat: "pdf" }) .done(function (link) { window.open(link.href); // open new window to download report }) .fail(function (err) { alert(err.message); }); } |
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); }); } |
The following example creates a user interface for exporting a report:
visualize({ auth: { ... } }, function (v) { var $select = buildControl("Export to: ", v.report.exportFormats), $button = $("#button"), report = v.report({ resource: "/public/Samples/Reports/5g.AccountsReport", container: "#container", success: function () { button.removeAttribute("disabled"); }, error: function (error) { console.log(error); } }); $button.click(function () { console.log($select.val()); report.export({ //export options here outputFormat: $select.val(), //exports all pages if not specified //pages: "1-2" }, function (link) { var url = link.href ? link.href : link; window.location.href = url; }, function (error) { console.log(error); }); }); function buildControl(name, options) { function buildOptions(options) { var template = "<option>{value}</option>"; return options.reduce(function (memo, option) { return memo + template.replace("{value}", option); }, "") } var template = "<label>{label}</label><select>{options}</select><br>", content = template.replace("{label}", name) .replace("{options}", buildOptions(options)); var $control = $(content); $control.insertBefore($("#button")); //return select return $($control[1]); } }); |
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> |
Refreshing a Report
visualize({ auth: { ... } }, function (v) { var alwasyRefresh = false; var report = v.report({ //skip report running during initialization 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> |
Canceling Report Execution
To stop a report that is executing, call its cancel function:
... report .cancel() .done(function(){ alert("Report Canceled"); }) .fail(function(){ alert("Report Failed"); }); |
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({ 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> |
Discovering Available Charts and Formats
You can write code to discover and display the types of charts and export formats that can be specified.
visualize({ auth: { name: "jasperadmin", password: "jasperadmin", organization: "organization_1" } }, function (v) { buildControl("Chart types", v.report.chart.types); buildControl("Report export formats", v.report.exportFormats); buildControl("Report table column types", v.report.table.column.types); }); 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)); } |