Visualizing Financial Flows in Oracle APEX with the Sankey PRO Plug-in

Wednesday, January 7, 2026

Financial data is full of relationships that are hard to see in tables and standard charts. Sankey diagrams make those flows obvious, and with the United Codes' APEX Sankey PRO Chart Plug-in, you can build them declaratively in Oracle APEX.


In this post, we will turn Oracle’s Q1 FY26 data into an interactive Sankey chart that runs natively in APEX using a single table, one SQL query, and a plug-in region, no custom JavaScript required.

Oracle’s Q1 FY26


Before diving into the code, let's take a quick look at the dataset we'll visualize. Oracle's Q1 FY26 results (ended August 31, 2025) provide a clear example of how cash flows through a modern SaaS and cloud business.


The data shows a clear shift from traditional software licensing to cloud services, with infrastructure driving most of the growth, which translates well into a flow-based visualization. Below is an excellent income statement visualization from App Economy Insights (appeconomyinsights.com) that inspired this post:


Figure 1: Oracle Q1 FY26 Income Statement visualisation from App Economy Insights (appeconomyinsights.com)



The goal is to recreate the clarity of the App Economy Insights income statement visualization directly in Oracle APEX, so you can make it interactive, filterable, and adaptable to your own data sources.


Building Your Financial Flow Visualization


The APEX Sankey PRO Chart Plug-in is powered by Plotly.js, making these visualizations straightforward to implement. Let's build this in three steps.

Step 1: Prepare your data


For this example, everything is stored in a single table that models the flow. Each row describes a link in the diagram: source node, target node, value, level, colors, growth, and display order. This structure keeps the data model simple while giving enough control to drive layout, tooltips, and color directly from SQL.


-- Single table for Oracle Q1 FY26 financial flows
CREATE TABLE orcl_financial_flows (
    flow_id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
    source_node VARCHAR2(100) NOT NULL,   -- Where the money comes from (e.g., "Cloud Services")
    target_node VARCHAR2(100) NOT NULL,    -- Where it goes (e.g., "Revenue")
    flow_value NUMBER(12,2) NOT NULL,         -- The dollar amount in millions
    flow_level NUMBER(2) NOT NULL,               -- Hierarchy level for proper ordering
    link_color VARCHAR2(7),                              -- Color of the flow line
    source_node_color VARCHAR2(7),               -- Color of the starting node
    target_node_color VARCHAR2(7),                -- Color of the ending node
    yoy_growth_pct NUMBER(6,2),                     -- Year-over-year growth percentage
    display_order NUMBER(4)                            -- Controls the rendering sequence
);


Step 2: Load Oracle's Q1 FY26 Financial Data


Now we populate the table with Oracle's actual numbers. The key is creating a connected waterfall where each level feeds into the next.

-- TIER 1: Detailed SaaS products → SaaS Applications (GRAY)
INSERT INTO orcl_financial_flows 
(source_node, target_node, flow_value, flow_level, link_color, source_node_color, target_node_color, yoy_growth_pct, display_order)
VALUES ('NetSuite Cloud ERP', 'SaaS Applications', 1000, 1, '#9b9998', '#31302c', '#9b9998', 16, 10);

INSERT INTO orcl_financial_flows 
(source_node, target_node, flow_value, flow_level, link_color, source_node_color, target_node_color, yoy_growth_pct, display_order)
VALUES ('Fusion Cloud Apps', 'SaaS Applications', 1800, 1, '#9b9998', '#31302c', '#9b9998', 20, 11);

INSERT INTO orcl_financial_flows 
(source_node, target_node, flow_value, flow_level, link_color, source_node_color, target_node_color, yoy_growth_pct, display_order)
VALUES ('Other SaaS Products', 'SaaS Applications', 1100, 1, '#9b9998', '#31302c', '#9b9998', 15, 12);

-- TIER 2: Cloud components → Cloud Services (GRAY)
INSERT INTO orcl_financial_flows 
(source_node, target_node, flow_value, flow_level, link_color, source_node_color, target_node_color, yoy_growth_pct, display_order)
VALUES ('Cloud Infrastructure (OCI)', 'Cloud Services', 3300, 2, '#9b9998', '#31302c', '#9b9998', 55, 20);

INSERT INTO orcl_financial_flows 
(source_node, target_node, flow_value, flow_level, link_color, source_node_color, target_node_color, yoy_growth_pct, display_order)
VALUES ('SaaS Applications', 'Cloud Services', 3900, 2, '#9b9998', '#9b9998', '#9b9998', 18, 21);

-- TIER 3: Software components → Software License & Support (GRAY)
INSERT INTO orcl_financial_flows 
(source_node, target_node, flow_value, flow_level, link_color, source_node_color, target_node_color, yoy_growth_pct, display_order)
VALUES ('Database Licenses', 'Software License & Support', 2500, 3, '#9b9998', '#31302c', '#9b9998', -2, 30);

INSERT INTO orcl_financial_flows 
(source_node, target_node, flow_value, flow_level, link_color, source_node_color, target_node_color, yoy_growth_pct, display_order)
VALUES ('Support Services', 'Software License & Support', 2000, 3, '#9b9998', '#31302c', '#9b9998', 1, 31);

INSERT INTO orcl_financial_flows 
(source_node, target_node, flow_value, flow_level, link_color, source_node_color, target_node_color, yoy_growth_pct, display_order)
VALUES ('Middleware & Apps License', 'Software License & Support', 1200, 3, '#9b9998', '#31302c', '#9b9998', -3, 32);

-- TIER 4: Major revenue streams → Revenue (GRAY converging to center)
INSERT INTO orcl_financial_flows 
(source_node, target_node, flow_value, flow_level, link_color, source_node_color, target_node_color, yoy_growth_pct, display_order)
VALUES ('Cloud Services', 'Revenue', 7200, 4, '#9b9998', '#9b9998', '#31302c', 28, 40);

INSERT INTO orcl_financial_flows 
(source_node, target_node, flow_value, flow_level, link_color, source_node_color, target_node_color, yoy_growth_pct, display_order)
VALUES ('Software License & Support', 'Revenue', 5700, 4, '#9b9998', '#9b9998', '#31302c', -1, 41);

INSERT INTO orcl_financial_flows 
(source_node, target_node, flow_value, flow_level, link_color, source_node_color, target_node_color, yoy_growth_pct, display_order)
VALUES ('Hardware & Services', 'Revenue', 2000, 4, '#9b9998', '#31302c', '#31302c', -2, 42);

-- TIER 5: Revenue split → Gross Profit (GREEN) / Cost of Revenue (RED)
INSERT INTO orcl_financial_flows 
(source_node, target_node, flow_value, flow_level, link_color, source_node_color, target_node_color, yoy_growth_pct, display_order)
VALUES ('Revenue', 'Gross profit', 10600, 5, '#a5c59b', '#31302c', '#499430', 8, 50);

INSERT INTO orcl_financial_flows 
(source_node, target_node, flow_value, flow_level, link_color, source_node_color, target_node_color, yoy_growth_pct, display_order)
VALUES ('Revenue', 'Cost of revenue', 4300, 5, '#d3978d', '#31302c', '#b22a16', 18, 51);

-- TIER 6: Gross Profit split → Operating Profit (GREEN) / Operating Expenses (RED)
INSERT INTO orcl_financial_flows 
(source_node, target_node, flow_value, flow_level, link_color, source_node_color, target_node_color, yoy_growth_pct, display_order)
VALUES ('Gross profit', 'Operating profit', 6200, 6, '#a5c59b', '#499430', '#499430', 9, 60);

INSERT INTO orcl_financial_flows 
(source_node, target_node, flow_value, flow_level, link_color, source_node_color, target_node_color, yoy_growth_pct, display_order)
VALUES ('Gross profit', 'Operating expenses', 4400, 6, '#d3978d', '#499430', '#b22a16', 7, 61);

-- TIER 7: Operating Profit → Net Profit (GREEN) / Tax & Interest (RED)
INSERT INTO orcl_financial_flows 
(source_node, target_node, flow_value, flow_level, link_color, source_node_color, target_node_color, yoy_growth_pct, display_order)
VALUES ('Operating profit', 'Net profit', 4300, 7, '#499430', '#499430', '#499430', 8, 70);

INSERT INTO orcl_financial_flows 
(source_node, target_node, flow_value, flow_level, link_color, source_node_color, target_node_color, yoy_growth_pct, display_order)
VALUES ('Operating profit', 'Tax & Interest', 1900, 7, '#d3978d', '#499430', '#b22a16', 11, 71);

For financial visualizations, colors carry meaning, so our example follows common conventions: gray for revenue sources, green for profit, and red for costs. Wider green bands indicate stronger profitability, while red bands highlight cost and margin impact at each step.


However, the plug-in supports custom colors for nodes and links, allowing you to color-code your nodes declaratively. The plug-in's Attributes Tab and its properties`link_color`, `source_node_color`, and `target_node_color` columns give you complete control over this visual language. 

Step 3: Configure the APEX Region


With the data in place, the rest is standard APEX configuration:

A. Create a UC – APEX Sankey Chart region

1.     Navigate to your APEX page

2.     Create a new region

3.     Type: UC - APEX Sankey Chart

4.     Title: "Oracle Q1 FY26 Financial Flows"


Figure 2: Create a UC – APEX Sankey Chart region type and give it a name.


B. Configure the Data Source

  • Location: Local Database
  • Type: SQL Query
  • SQL Query:

Figure 3: SQL Query for our UC – APEX Sankey Chart region.



SELECT
    source_node AS source,
    target_node AS target,
    flow_value AS transition_count,
    link_color,
    -- Build rich tooltips with financial context
    '<b>' || source_node || ' → ' || target_node || '</b><br>' ||
    '<b>Amount:</b> $' || TRIM(TO_CHAR(flow_value, '999,999')) || 'M<br>' ||
    CASE
        WHEN yoy_growth_pct IS NOT NULL
        THEN '<b>Growth:</b> ' ||
             CASE WHEN yoy_growth_pct > 0 THEN '+' ELSE '' END ||
             TO_CHAR(yoy_growth_pct, 'FM999990.0') || '% YoY<br>'
        ELSE ''
    END ||
    CASE
        WHEN target_node = 'Gross profit' THEN '<b>Gross Margin:</b> 71.1%<br>'
        WHEN target_node = 'Operating profit' THEN '<b>Operating Margin:</b> 41.6%<br>'
        WHEN target_node = 'Net profit' THEN '<b>Net Margin:</b> 28.9%<br><b>EPS:</b> $1.47<br>'
        ELSE ''
    END AS custom_tooltip,
    source_node_color,
    target_node_color
FROM orcl_financial_flows
ORDER BY display_order;


C. Map the Columns (Region’s Attributes Tab)


Configure how the plug-in interprets your data:

  • Source Column: SOURCE ← Starting point of each flow
  • Target Column: TARGET ← Ending point of each flow
  • Weight Column: TRANSITION_COUNT  ← Size of the flow (determines width)
  • Link Color Column: LINK_COLOR ← Color of the connecting flow
  •  Link Tooltip Column: CUSTOM_TOOLTIP ← Rich HTML tooltip on hover
  •  Source Node Color Column: SOURCE_NODE_COLOR ← Color of source node
  • Target Node Color Column: TARGET_NODE_COLOR ← Color of the target node

Figure 4: UC – APEX Sankey Chart region Attributes let you customize the appearance of your Sankey Chart.



Pro Tip: The Weight Column drives visual proportions: larger values create thicker flows, making important relationships immediately visible.


D. Customize Appearance


Node interaction, region height, and performance options like Lazy Loading are all controlled declaratively, just like other APEX region types.


At this point, your Sankey chart is functional and displays Oracle's financial flows beautifully.


Here is our result:

Figure 5: Oracle Q1 FY26 Financial Flows in Oracle APEX.



If you click the camera icon in the top-right corner of the region, you can download your Sankey chart as a .png file.


What We've Built


In three steps, we have built an APEX region that:

  • Renders the full Q1 FY26 income statement as a Sankey chart from a single table
  • Uses configurable colors and HTML tooltips driven entirely from SQL
  • Runs as a standard UC – APEX Sankey Chart region with a SQL data source, no custom JavaScript


To adapt this to your projects, swap in your own table, adjust the color rules, or extend the query with more metrics while keeping the same region configuration.


Conclusion


The APEX Sankey PRO Chart Plug-in provides APEX developers with a declarative way to convert complex financial structures into readable flow diagrams. Instead of combining multiple charts, you model flows once in a table and let the plug-in handle layout, proportions, and interactivity.


The same pattern works for income statements, budgets, allocations, and any process where “where it comes from” and “where it goes” matter more than the detail lines.


Resources & Links

Download the plug-in: https://www.united-codes.com/products/plug-ins-pro/docs/sankey-chart-pro/getting-started/download/

Full Documentation: https://www.united-codes.com/products/plug-ins-pro/docs/sankey-chart-pro/

Sample Application: https://www.united-codes.com/products/plug-ins-pro/docs/sankey-chart-pro/getting-started/live-demo/


Acknowledgments

Thank you, Aleš Kravos, for the blog idea, comments, suggestions, and reviews.

Picture of Ines Repnik

Ines Repnik

Developer

Developer - APEX Project Eye

Comments

No comments yet, be the first one to let us know what you think of this article!