Processes
The process explorer is process mining in the page. Give it an event log - one row for each thing done to a case, exported from an ERP, CRM, ticketing or workflow system, as CSV, XES or JSON - and it draws how the work really flows: every activity and hand-over, heavier the more cases take it, or coloured by how long cases wait.
Sliders keep only the activities and paths that matter; a replay moves every case through the map over time. The variants (the different ways cases went), every case with its timeline, conformance against the path cases are meant to take - skipped, extra, repeated and out-of-order steps - and statistics. Filter by date, duration, activity, variant or any attribute, from the map or a filter bar. The log never leaves the page.
Purchase to pay
Four hundred purchase orders at a fictional supplier, checked against the path they are meant to take (approval is optional for small orders). Switch the map to Duration to see where orders wait, choose a path to see its waits, press play, or open Conformance to see who skipped what.
Get the code
<script src="/assets/bmx-components.min.js"></script>
<bmx-process-explorer id="pe-p2p" reference='{"path":["Create requisition","Approve requisition","Create purchase order","Send purchase order","Receive goods","Receive invoice","Match invoice","Pay invoice"],"optional":["Approve requisition"]}' style="inline-size: 100%; --bmx-process-explorer-height: 32rem"></bmx-process-explorer>
Straight from a CSV export
A help desk's export, pasted in as it comes - semicolons, a header naming the columns ticket,
step, created and agent, which the explorer recognises - and shown across
the page. Reopened and escalated tickets stand out as loops.
// Node 18 or later: the process-mining engine, from the Gold package.
import { readEventLog, variantsOf, bottlenecks, discoverMap, checkConformance, readReference, casesToCsv } from './dist/node/bmx-process-explorer.mjs';
// Every night: last month's orders from the ERP, the slowest hand-overs and the cases that strayed.
const log = readEventLog(await readFile('orders.csv', 'utf8'));
const slowest = bottlenecks(discoverMap(log.cases), 5);
const conformance = checkConformance(log.cases, readReference('Order → Approve → Ship → Invoice → Pay'));
await writeFile('cases.csv', casesToCsv(log.cases, variantsOf(log.cases), conformance));
await postToChannel({ slowest, conforming: conformance.rate });