Reports
A report is a JSON definition and an array of rows. The report viewer lays them out into pages — grouped, sorted, totalled and formatted — and shows them the way they will print. Search them, jump through their contents, change their parameters, print them, or save them as a PDF. All of it happens in the browser: there is no report server to run and nothing to install.
The pages are laid out once and drawn three ways — on screen, on paper and in the PDF — from the same lines, so what you see is what prints. The PDF is tagged, with headings, reading order and the page furniture marked, so it can be read aloud.
Reports carry charts, crosstabs and barcodes, in any alphabet your fonts cover. Readers open and close groups, sort by a heading and click through to the detail behind a figure, then take the result away as a PDF, an Excel workbook, a CSV file or a web page.
The report designer is where those definitions are made: drag fields onto bands, group and total them, style and format them, and preview the result — in the browser too, so your application can let its own users design their reports.
Sales by region
A year of orders, grouped by region with a subtotal and its share of the whole, a grand total, and the page numbers at the foot. Open Parameters and choose a region or a minimum order; the report runs again. Type a customer into Find and every match is highlighted. The side panel has page thumbnails and the contents, built from the report's own group bookmarks.
The definition is data, not code. Every computed value — a total, a filter, the
rule that turns a large order green — is an expression in a small closed language:
sum(amount), amount / sum(amount, 'report'),
iif(amount >= 5000, ...). Nothing in a report is ever run as script, so a definition
kept in a database, or written by a user, is safe to open.
Get the code
<script src="/assets/bmx-components.min.js"></script>
<bmx-report-viewer id="rep-sales" sidebar="contents" style="--bmx-report-viewer-height: 44rem"></bmx-report-viewer>
<script>
const reportViewer = document.getElementById('rep-sales');
reportViewer.data = [ /* your data */ ];
reportViewer.report = { /* your report definition */ };
</script>
Report designer
The same sales report, open in the designer. Drag a field from the list onto a band — in a header it becomes a caption, in the detail its value, in a footer its total. Move and resize items and they snap to the grid and to each other; drag a band's lower edge to make it taller. Select anything to edit it on the right: every expression field completes as you type, and fx opens the builder with each function's help and the result on the first row. Preview runs the report; New report lays out a list, a grouped report, a summary or a form letter for the data's own fields.
The designer writes the same JSON the viewer reads. Listen for
bmxReportChange to follow every edit, or bmxReportSave to store the
definition where your application keeps its data — cancel it, and the designer leaves the saving
to you.
Get the code
<script src="/assets/bmx-components.min.js"></script>
<bmx-report-designer id="rep-designer" style="--bmx-report-designer-height: 46rem"></bmx-report-designer>
<script>
const reportDesigner = document.getElementById('rep-designer');
reportDesigner.data = [ /* your data */ ];
reportDesigner.report = { /* your report definition */ };
</script>
Charts, crosstabs and barcodes
The overview is one report: three charts drawn from the same orders - the first with the sales as columns and the number of orders as a line on a second axis - and a crosstab of every customer by quarter, with a subtotal for each region. The crosstab is longer than a page, so its band splits across pages, the column headings are printed again at the top of each, and the region the first row is still under is named again. The labels print two to a row, a sheet of labels, each with a Code 128 barcode, an EAN-13 and a QR code. Every chart and code is drawn as shapes, not pictures: sharp at any zoom, small in the PDF, and described there for a screen reader.
Get the code
<script src="/assets/bmx-components.min.js"></script>
<bmx-report-viewer id="rep-items" zoom="page-width" style="--bmx-report-viewer-height: 40rem"></bmx-report-viewer>
<script>
const reportViewer = document.getElementById('rep-items');
reportViewer.data = [ /* your data */ ];
reportViewer.report = { /* your report definition */ };
</script>
Drill down, sort, drill through
Each region starts closed: press the arrow beside it to show its orders. Click a column heading to sort by it, and again to reverse it. Click a customer to open their own report, with a chart of their orders; Back returns to where you were. Export saves the report's data as an Excel workbook or a CSV file, or its pages as a web page.
Nothing here asks the server. Opening a group, sorting and drilling through lay the
report out again from the rows already in the page. Give drillData a function to fetch a
customer's own rows instead, or listen for bmxReportDrill and open the detail somewhere else.
Get the code
<script src="/assets/bmx-components.min.js"></script>
<bmx-report-viewer id="rep-reading" style="--bmx-report-viewer-height: 36rem"></bmx-report-viewer>
<script>
const reportViewer = document.getElementById('rep-reading');
reportViewer.data = [ /* your data */ ];
reportViewer.report = { /* your report definition */ };
</script>
Any alphabet
A report can name its own TrueType fonts. This one uses a font with Greek, Cyrillic and the accents of central Europe and Vietnam, so every line below is real text in the PDF: save it and search it, copy from it, or have it read aloud. The PDF carries only the characters the report uses.
Get the code
<script src="/assets/bmx-components.min.js"></script>
<bmx-report-viewer id="rep-fonts" zoom="page-width" style="--bmx-report-viewer-height: 30rem"></bmx-report-viewer>
<script>
const reportViewer = document.getElementById('rep-fonts');
reportViewer.data = [ /* your data */ ];
reportViewer.report = { /* your report definition */ };
</script>
Large reports
Layout runs in slices, handing the page back between them, so a report of tens of thousands of rows never freezes it; and only the pages in view are in the document. Press the button to run the same report over fifty thousand orders.
Get the code
<script src="/assets/bmx-components.min.js"></script>
<bmx-report-viewer id="rep-large" zoom="whole-page" style="--bmx-report-viewer-height: 34rem"></bmx-report-viewer>
<script>
const reportViewer = document.getElementById('rep-large');
reportViewer.data = [ /* your data */ ];
reportViewer.report = { /* your report definition */ };
</script>