Visualizing Financial Flows in Oracle APEX with the Sankey PRO Plugin

The Sankey PRO plugin for Oracle APEX promises a lot. Drop it on a page, point it at a SQL query, and you get a beautiful flow diagram. For simple cases, that’s largely true. But when you’re working against a real general ledger — with multi-level account hierarchies, intercompany eliminations, and period-close adjustments — the gap between “works in the demo” and “works in production” becomes interesting.

What the Plugin Actually Does

Sankey PRO takes a flat dataset with three columns: source, target, and value. It handles everything visual from there — node sizing, link curvature, tooltips, color assignment. The plugin is genuinely good at its job.

What it doesn’t do is think about your data model. That part is yours.

Modeling the Ledger

Our chart of accounts has five levels. A P&L Sankey typically wants two or three. So before the plugin sees anything, I need a query that collapses account hierarchies into the right granularity.

WITH account_rollup AS (
    SELECT
        t.period_name,
        a.segment1                      AS account_code,
        a.description                   AS account_name,
        ga.parent_flex_value            AS parent_code,
        pa.description                  AS parent_name,
        SUM(t.accounted_dr - t.accounted_cr) AS net_amount
    FROM
        gl_je_lines t
        JOIN fnd_flex_values_vl a  ON a.flex_value = t.code_combination_id
        JOIN fnd_flex_value_hierarchies h ON h.child_flex_value = a.flex_value
        JOIN fnd_flex_values_vl pa ON pa.flex_value = h.parent_flex_value
    WHERE
        t.period_name = :P_PERIOD
        AND t.ledger_id = :P_LEDGER_ID
    GROUP BY
        t.period_name, a.segment1, a.description,
        h.parent_flex_value, pa.description
)
SELECT parent_name AS source, account_name AS target, ABS(net_amount) AS value
FROM   account_rollup
WHERE  net_amount <> 0

This is simplified — real hierarchies require a recursive CTE or a pre-flattened rollup table. But the shape is right: every row is an edge in the graph.

Where the Abstraction Leaks

Two things surprised me in production:

Sign conventions. The Sankey plugin treats all values as positive flows. GL balances are signed — debits positive, credits negative depending on account type. You’ll want to apply a sign flip based on account_type before the data reaches the plugin, or flows for expense accounts will run backwards.

Circular references. Intercompany transactions create cycles in the flow graph that Sankey diagrams can’t represent. The plugin silently drops cyclic edges. Worth adding a validation step that flags these before they disappear.

The Result

Once the data model is right, the plugin does what it promises. Our finance team can now see cash flowing from revenue categories down through cost centers without opening a pivot table. The visual is genuinely useful — it surfaced three allocation rules that had been wrong for two years.

The lesson isn’t that Sankey PRO is hard. It’s that the interesting work in data visualization is usually upstream of the chart.

A quiet email, when there's something worth saying.

APEX, PL/SQL, data, automations and AI workflows, and notes from conference weekends. No schedule, no tracking, no fluff. Unsubscribe in one click.