@panosoft/chronicle

0.10.3 • Public • Published

Chronicle

Create Reports with Web Technologies and run them in Node.

Chronicle

npm version Travis

Finally, a reporting engine for JavaScript!

Writing Reports is as easy as writing CommonJS modules (i.e. Node modules) and they can pull data from any source (APIs, SQL Servers, Code data generation, etc.).

The following Web Technologies are supported for use in Reports:

  • HTML + Handlebars
  • CSS + LESS
  • JavaScript + Browserify + npm

Contents

Architecture

Reports are CommonJS modules (i.e. Node modules) that export a Report Function.

Report Functions accept runtime parameters, retrieve data, and generate HTML.

Chronicle bundle can be used to bundle Reports. Bundling reduces a Report Module, and all of it's dependencies, into a single, portable, version locked file. As such, bundling makes transporting Reports across networks a trivial task.

Chronicle runs Reports. It accepts a variety of inputs: urls to Bundles, paths to Modules, or references to Report Functions. Running a Report loads the Report Function, evaluates it, and returns it's HTML output.

Finally, HTML renderers like PrinceXML that support CSS Paged Media can be used to generate PDFs complete with page headers, footers, numbers, etc.!


![Architecture](docs/architecture.png)

Philosophy

Unlike Crystal Reports, Jasper Reports, BIRT, SQL Server Reporting Services (SSRS), Pentaho, etc., Chronicle doesn't subscribe to the WYSIWYG approach to report development. This is reminiscent of using FrontPage to produce web pages.

With the WYSIWYG approach, most powerful features are hidden and buried under menu items, property sheets and require a half a dozen clicks to expose the correct radio button or check box. And many times, the powerful features just aren't there.

Anyone who has had to suffer through these poorly designed systems has quickly realized that reports are harder than they need to be and that one must contort oneself in order to accomplish what would be trivial in a programming language.

Another big problem with these traditional reporting systems, is that since it has a GUI, people assume that anyone can build a report. While it's true that anyone can, not everyone should.

Good reports transform data into useful information in a form that's easy to understand. This is not a trivial task that you can give the receptionist or the intern. This requires layout design, data processing and logic. These are all things that good developers are skilled at, particularly web developers.

Chronicle embraces these truths and caters to developers by using standard Web Technologies, viz. HTML/Handlebars, CSS/Less, Javascript, NodeJS, Browserify and PrinceXML to produce high quality PDF reports from any data source.

Usage

Reports can be run from the command line:

chronicle run report.js

Or using the Node api:

var co = require('co');
var chronicle = require('@panosoft/chronicle');
var prince = require('prince-promise');

co(function * () {

  var html = yield chronicle.run('report.js');

  var pdf = yield prince(html);

});

Examples

Installation

npm install -g @panosoft/chronicle

Report Structure

Reports can take the form of a simple Function or a Module that exports a Function.

They are run by Chronicle which returns static HTML content that can be visually rendered by a browser or any other third party HTML renderers.

Module

A report Module is simply a CommonJS module (i.e. Node module) that exports a report Function.

Report Modules can optionally be bundled using Chronicle bundle so that all of their dependencies are contained within a single file.

Chronicle can then run a Report using a url that references a bundled Module, a path to a local Module, or by simply passing the Function itself.

Example

var report = function (parameters) {
  // ...
};

module.exports = report;

Function

The Report Function retrieves data and renders it as HTML.

This can be an ordinary or a yieldable function that accepts runtime parameters and returns static HTML.

Examples

Simplistic:

const report = function (parameters) {
  const context = { date: parameters.date };
  const html = `Created: ${{context.date}}`;
  return html;
};

Realistic:

const co = require('co');
const Handlebars = require('handlebars');
const inlineHtml = require('inline-html');

const getContext = co.wrap(function * (parameters) {
  // Fetch and process data
  // return the template context.
  return context;
};

const render = co.wrap(function * (context) {
  // Define helpers
  const helpers = {
    // ...
  };
  // Define partials
  const partials = {
    // ...
  };
  // Load template source
  const source = yield inlineHtml.file('path/to/template.html');
  // Compile source and evaluate template
  const template = Handlebars.compile(source);
  const html = template(context, { helpers, partials });
  return html;
});

const report = co.wrap(function * (parameters) {
  const context = yield getContext(parameters);
  const html = yield render(context);
  return html;
});

CLI

chronicle


bundle [entry] [--output] [--watch]

Bundles a report Module along with all of its dependencies into a single file called a bundle.

Bundles are completely self contained and thus very portable. For instance, bundles could be stored on a static file server and requested remotely by Chronicle when run.

Since bundle uses Browserify internally, all Browserify compatible Modules can be bundled. Browserify transforms can also be used simply by including them in the Modules package.json in the standard way.

Arguments

  • entry - The main entry filename of a report Module to bundle. If an entry is not specified, the package.json's' main property will be used. If the package.json doesn't exist or if the main property is not specified, then index.js will be used as the entry.

  • -o, --output - The filename for the bundled module. Defaults to bundle.js.

  • -w, --watch - Enable watch mode. As files are modified, the bundle will be updated automatically and incrementally.

Examples

chronicle bundle -w
chronicle bundle entry.js -o output.js -w

run [report] [--parameters] [--output]

Runs a report and returns the output. If the output is an Array or Object, it is returned as a JSON string.

Arguments

  • report - The report to run. Supported values are:

    • A fully qualified url - Load a bundled report Module from a url.
    • A filename - Load a report Module (bundled or not) from the filesystem.
    • No value - Read from stdin. The value passed in can be any of the above.
  • -o, --output - The destination for the report HTML to be written. Supported values are:

    • A filename - Write to the filesystem.
    • No value - Write to stdout
  • -p, --parameters - A JSON parseable string of parameters to run the report with.

Examples

chronicle run index.js
chronicle run bundle.js -o report.html -p '{"sample": "parameter"}'

API

chronicle


bundle ( entry , options )

Bundles a report Module along with all of its dependencies into a single file called a bundle.

Since bundle uses Browserify internally, all Browserify compatible Modules can be bundled. Browserify transforms can also be used simply by including them in the Modules package.json in the standard way.

Upon completion, the bundle is written directly to the filesystem per output option.

Arguments

  • entry - The main entry filename of a report Module to bundle. If an entry is not specified, the package.json's' main property will be used. If the package.json doesn't exist or if the main property is not specified, then index.js will be used as the entry.

  • options

    • output - The filename for the bundled Module. Defaults to bundle.js.
    • watch - A boolean used to enable watch mode. Supported values are:
      • true - The Module is bundled and as files are modified, the bundle is updated automatically and incrementally.
      • false - The Module is bundled once. (default)

Example

var entry = 'index.js';
var options = {
  output: 'bundle.js'
};

chronicle.bundle(entry, options);

run ( report , parameters )

Runs a Report and returns a Promise that is fulfilled with the HTML produced.

The Report is loaded, evaluated, and the HTML output is returned.

Arguments

  • report - The Report to run. Supported values are:

    • A fully qualified url of a bundled report Module.
    • A filename of a report Module (bundled or not).
    • A report Function.
  • parameters - An object of parameters used to run the report. This object is passed to the report Function at runtime.

Examples

var report = 'bundle.js';
var parameters = {};

press.run(report, parameters)
  .then(function (html) {
    // ...
  });

Package Sidebar

Install

npm i @panosoft/chronicle

Weekly Downloads

5

Version

0.10.3

License

ISC

Last publish

Collaborators

  • panosoft