Transformation Function
AOP allows the use of transformation function for more flexible data modification using functions. The transform() function is executed internally by AOP, serving as the main function within the transformation_function
and the returned value from this function becomes the new data key for AOP during document rendering. You can define new variables and functions within this context, similar to how it's done in JavaScript.
For testing of transformation_function, On-premises users can use AOP Webeditor.
Alternatively, instead of providing lengthy functions directly, From: v25.1, AOP now supports referencing a filename for the transformation function. The file must be located in the AOP Directory > assets > transformation_functions > [tfn_file.js]
. For the complete example refer to Example III
Example-I
This example demonstrates the usage of transformation function for the styling of table and breaking of data based on category to create a HTML content.
Data Source
Hereby examples of data source for different options.
- SQL
- PL/SQL returning SQL
- PL/SQL returning JSON
- JSON
select
'file1' as "filename",
cursor(
select
c.cust_first_name as "cust_first_name",
c.cust_last_name as "cust_last_name",
cursor(
select
p.product_name as "product_name",
i.unit_price as "unit_price",
i.quantity as "quantity",
p.category as "category"
from
aop_sample_order_items i,
aop_sample_product_info p
where
o.order_id = i.order_id
and i.product_id = p.product_id
) "product"
from
aop_sample_orders o,
aop_sample_customers c
where
c.customer_id = o.customer_id
and c.customer_id = 1
) as "data"
from
dual;
declare
l_return clob;
begin
l_return := q'[
select
'file1' as "filename",
cursor(
select
c.cust_first_name as "cust_first_name",
c.cust_last_name as "cust_last_name",
cursor(
select
p.product_name as "product_name",
i.unit_price as "unit_price",
i.quantity as "quantity",
p.category as "category"
from
aop_sample_order_items i,
aop_sample_product_info p
where
o.order_id = i.order_id
and i.product_id = p.product_id
) "product"
from
aop_sample_orders o,
aop_sample_customers c
where
c.customer_id = o.customer_id
and c.customer_id = 1
) as "data"
from
dual;
]';
return l_return;
end;
declare
l_cursor sys_refcursor;
l_return clob; -- can also be varchar2, make sure it corresponds to the structure in the JSON
begin
apex_json.initialize_clob_output(dbms_lob.call, true, 2);
open l_cursor for
select
'file1' as "filename",
cursor(
select
c.cust_first_name as "cust_first_name",
c.cust_last_name as "cust_last_name",
cursor(
select
p.product_name as "product_name",
i.unit_price as "unit_price",
i.quantity as "quantity",
p.category as "category"
from
aop_sample_order_items i,
aop_sample_product_info p
where
o.order_id = i.order_id
and i.product_id = p.product_id
) "product"
from
aop_sample_orders o,
aop_sample_customers c
where
c.customer_id = o.customer_id
and c.customer_id = 1
) as "data"
from
dual;
apex_json.write(l_cursor);
l_return := apex_json.get_clob_output;
return l_return;
end;
[
{
"filename": "file1",
"data": [
{
"cust_first_name": "John",
"cust_last_name": "Dulles",
"product": [
{
"product_name": "Business Shirt",
"unit_price": 50,
"quantity": 3,
"category": "Mens"
},
{
"product_name": "Trousers",
"unit_price": 80,
"quantity": 3,
"category": "Mens"
},
{
"product_name": "Jacket",
"unit_price": 150,
"quantity": 3,
"category": "Mens"
},
{
"product_name": "Blouse",
"unit_price": 60,
"quantity": 3,
"category": "Womens"
},
{
"product_name": "Skirt",
"unit_price": 80,
"quantity": 3,
"category": "Womens"
},
{
"product_name": "Ladies Shoes",
"unit_price": 120,
"quantity": 2,
"category": "Womens"
},
{
"product_name": "Belt",
"unit_price": 30,
"quantity": 2,
"category": "Accessories"
},
{
"product_name": "Bag",
"unit_price": 125,
"quantity": 4,
"category": "Accessories"
},
{
"product_name": "Mens Shoes",
"unit_price": 110,
"quantity": 2,
"category": "Mens"
},
{
"product_name": "Wallet",
"unit_price": 50,
"quantity": 2,
"category": "Accessories"
}
]
}
]
}
]
The data ganerated from SQL is further processed by AOP when transformation function is provided. Hearby the transformation function:
- Init PL/SQL Code
- JSON
- Javascript
aop_api_pkg.g_transformation_function := 'function generateProductRows(products, category) {\r\n return products\r\n .filter(product => product.category === category)\r\n .map(product => {\r\n if (category === \"Mens\") {\r\n product.category_bold = \"true\";\r\n product.product_name_font_color = \"blue\";\r\n } else {\r\n product.category_italic = \"true\";\r\n product.product_name_font_color = \"red\";\r\n }\r\n const totalCost = product.unit_price * product.quantity;\r\n return `\r\n <tr>\r\n <td style=\"border-width: 1px; border-style: solid; border-color: black; padding: 8px;\">${product.product_name}</td>\r\n <td style=\"border-width: 1px; border-style: solid; border-color: black; padding: 8px;\">${product.unit_price}</td>\r\n <td style=\"border-width: 1px; border-style: solid; border-color: black; padding: 8px;\">${product.quantity}</td>\r\n <td style=\"border-width: 1px; border-style: solid; border-color: black; padding: 8px;\">${totalCost}</td>\r\n </tr>\r\n `;\r\n })\r\n .join('');\r\n}\r\n\r\nfunction transform() {\r\n files.forEach(file => {\r\n file.data.forEach(data => {\r\n // Initialize HTML strings for mens_products and womens_products\r\n let mensProductsHtml = '<table style=\"width: 100%; border: 2px solid blue; border-collapse: collapse;\">';\r\n let womensProductsHtml = '<table style=\"width: 100%; border: 2px solid red; border-collapse: collapse;\">';\r\n\r\n // Add table headers\r\n const tableHeaders = `\r\n <tr>\r\n <th style=\"border-width: 1px; border-style: solid; border-color: black; padding: 8px;\">Product Name</th>\r\n <th style=\"border-width: 1px; border-style: solid; border-color: black; padding: 8px;\">Unit Price</th>\r\n <th style=\"border-width: 1px; border-style: solid; border-color: black; padding: 8px;\">Quantity</th>\r\n <th style=\"border-width: 1px; border-style: solid; border-color: black; padding: 8px;\">Total Cost</th>\r\n </tr>\r\n `;\r\n mensProductsHtml += tableHeaders;\r\n womensProductsHtml += tableHeaders;\r\n\r\n // Generate HTML rows for mens and womens products\r\n const mensProductsRows = generateProductRows(data.product, \"Mens\");\r\n const womensProductsRows = generateProductRows(data.product, \"Womens\");\r\n\r\n // Calculate totals using reduce\r\n const mensTotals = data.product\r\n .filter(product => product.category === \"Mens\")\r\n .reduce((totals, product) => {\r\n totals.quantity += product.quantity;\r\n totals.cost += product.unit_price * product.quantity;\r\n return totals;\r\n }, { quantity: 0, cost: 0 });\r\n\r\n const womensTotals = data.product\r\n .filter(product => product.category === \"Womens\")\r\n .reduce((totals, product) => {\r\n totals.quantity += product.quantity;\r\n totals.cost += product.unit_price * product.quantity;\r\n return totals;\r\n }, { quantity: 0, cost: 0 });\r\n\r\n // Close the HTML tables\r\n mensProductsHtml += mensProductsRows + '</table>';\r\n womensProductsHtml += womensProductsRows + '</table>';\r\n\r\n // Add the new entries to the data object\r\n data.mens_products = mensProductsHtml;\r\n data.womens_products = womensProductsHtml;\r\n data.mens_total_quantity = mensTotals.quantity;\r\n data.mens_total_cost = mensTotals.cost;\r\n data.womens_total_quantity = womensTotals.quantity;\r\n data.womens_total_cost = womensTotals.cost;\r\n });\r\n });\r\n return files;\r\n}\r\n';
"transformation_function": "function generateProductRows(products, category) {\r\n return products\r\n .filter(product => product.category === category)\r\n .map(product => {\r\n if (category === \"Mens\") {\r\n product.category_bold = \"true\";\r\n product.product_name_font_color = \"blue\";\r\n } else {\r\n product.category_italic = \"true\";\r\n product.product_name_font_color = \"red\";\r\n }\r\n const totalCost = product.unit_price * product.quantity;\r\n return `\r\n <tr>\r\n <td style=\"border-width: 1px; border-style: solid; border-color: black; padding: 8px;\">${product.product_name}</td>\r\n <td style=\"border-width: 1px; border-style: solid; border-color: black; padding: 8px;\">${product.unit_price}</td>\r\n <td style=\"border-width: 1px; border-style: solid; border-color: black; padding: 8px;\">${product.quantity}</td>\r\n <td style=\"border-width: 1px; border-style: solid; border-color: black; padding: 8px;\">${totalCost}</td>\r\n </tr>\r\n `;\r\n })\r\n .join('');\r\n}\r\n\r\nfunction transform() {\r\n files.forEach(file => {\r\n file.data.forEach(data => {\r\n // Initialize HTML strings for mens_products and womens_products\r\n let mensProductsHtml = '<table style=\"width: 100%; border: 2px solid blue; border-collapse: collapse;\">';\r\n let womensProductsHtml = '<table style=\"width: 100%; border: 2px solid red; border-collapse: collapse;\">';\r\n\r\n // Add table headers\r\n const tableHeaders = `\r\n <tr>\r\n <th style=\"border-width: 1px; border-style: solid; border-color: black; padding: 8px;\">Product Name</th>\r\n <th style=\"border-width: 1px; border-style: solid; border-color: black; padding: 8px;\">Unit Price</th>\r\n <th style=\"border-width: 1px; border-style: solid; border-color: black; padding: 8px;\">Quantity</th>\r\n <th style=\"border-width: 1px; border-style: solid; border-color: black; padding: 8px;\">Total Cost</th>\r\n </tr>\r\n `;\r\n mensProductsHtml += tableHeaders;\r\n womensProductsHtml += tableHeaders;\r\n\r\n // Generate HTML rows for mens and womens products\r\n const mensProductsRows = generateProductRows(data.product, \"Mens\");\r\n const womensProductsRows = generateProductRows(data.product, \"Womens\");\r\n\r\n // Calculate totals using reduce\r\n const mensTotals = data.product\r\n .filter(product => product.category === \"Mens\")\r\n .reduce((totals, product) => {\r\n totals.quantity += product.quantity;\r\n totals.cost += product.unit_price * product.quantity;\r\n return totals;\r\n }, { quantity: 0, cost: 0 });\r\n\r\n const womensTotals = data.product\r\n .filter(product => product.category === \"Womens\")\r\n .reduce((totals, product) => {\r\n totals.quantity += product.quantity;\r\n totals.cost += product.unit_price * product.quantity;\r\n return totals;\r\n }, { quantity: 0, cost: 0 });\r\n\r\n // Close the HTML tables\r\n mensProductsHtml += mensProductsRows + '</table>';\r\n womensProductsHtml += womensProductsRows + '</table>';\r\n\r\n // Add the new entries to the data object\r\n data.mens_products = mensProductsHtml;\r\n data.womens_products = womensProductsHtml;\r\n data.mens_total_quantity = mensTotals.quantity;\r\n data.mens_total_cost = mensTotals.cost;\r\n data.womens_total_quantity = womensTotals.quantity;\r\n data.womens_total_cost = womensTotals.cost;\r\n });\r\n });\r\n return files;\r\n}\r\n"
function generateProductRows(products, category) {
return products
.filter(product => product.category === category)
.map(product => {
if (category === "Mens") {
product.category_bold = "true";
product.product_name_font_color = "blue";
} else {
product.category_italic = "true";
product.product_name_font_color = "red";
}
const totalCost = product.unit_price * product.quantity;
return `
<tr>
<td style="border-width: 1px; border-style: solid; border-color: black; padding: 8px;">${product.product_name}</td>
<td style="border-width: 1px; border-style: solid; border-color: black; padding: 8px;">${product.unit_price}</td>
<td style="border-width: 1px; border-style: solid; border-color: black; padding: 8px;">${product.quantity}</td>
<td style="border-width: 1px; border-style: solid; border-color: black; padding: 8px;">${totalCost}</td>
</tr>
`;
})
.join('');
}
function transform() {
files.forEach(file => {
file.data.forEach(data => {
// Initialize HTML strings for mens_products and womens_products
let mensProductsHtml = '<table style="width: 100%; border: 2px solid blue; border-collapse: collapse;">';
let womensProductsHtml = '<table style="width: 100%; border: 2px solid red; border-collapse: collapse;">';
// Add table headers
const tableHeaders = `
<tr>
<th style="border-width: 1px; border-style: solid; border-color: black; padding: 8px;">Product Name</th>
<th style="border-width: 1px; border-style: solid; border-color: black; padding: 8px;">Unit Price</th>
<th style="border-width: 1px; border-style: solid; border-color: black; padding: 8px;">Quantity</th>
<th style="border-width: 1px; border-style: solid; border-color: black; padding: 8px;">Total Cost</th>
</tr>
`;
mensProductsHtml += tableHeaders;
womensProductsHtml += tableHeaders;
// Generate HTML rows for mens and womens products
const mensProductsRows = generateProductRows(data.product, "Mens");
const womensProductsRows = generateProductRows(data.product, "Womens");
// Calculate totals using reduce
const mensTotals = data.product
.filter(product => product.category === "Mens")
.reduce((totals, product) => {
totals.quantity += product.quantity;
totals.cost += product.unit_price * product.quantity;
return totals;
}, { quantity: 0, cost: 0 });
const womensTotals = data.product
.filter(product => product.category === "Womens")
.reduce((totals, product) => {
totals.quantity += product.quantity;
totals.cost += product.unit_price * product.quantity;
return totals;
}, { quantity: 0, cost: 0 });
// Close the HTML tables
mensProductsHtml += mensProductsRows + '</table>';
womensProductsHtml += womensProductsRows + '</table>';
// Add the new entries to the data object
data.mens_products = mensProductsHtml;
data.womens_products = womensProductsHtml;
data.mens_total_quantity = mensTotals.quantity;
data.mens_total_cost = mensTotals.cost;
data.womens_total_quantity = womensTotals.quantity;
data.womens_total_cost = womensTotals.cost;
});
});
return files;
}
AOP executes the transformation_function
internally that gives the following modified data:
- JSON
[
{
"filename": "file1",
"data": [
{
"cust_first_name": "John",
"cust_last_name": "Dulles",
"product": [
{
"product_name": "Business Shirt",
"unit_price": 50,
"quantity": 3,
"category": "Mens",
"category_bold": "true",
"product_name_font_color": "blue"
},
{
"product_name": "Trousers",
"unit_price": 80,
"quantity": 3,
"category": "Mens",
"category_bold": "true",
"product_name_font_color": "blue"
},
{
"product_name": "Jacket",
"unit_price": 150,
"quantity": 3,
"category": "Mens",
"category_bold": "true",
"product_name_font_color": "blue"
},
{
"product_name": "Blouse",
"unit_price": 60,
"quantity": 3,
"category": "Womens",
"category_italic": "true",
"product_name_font_color": "red"
},
{
"product_name": "Skirt",
"unit_price": 80,
"quantity": 3,
"category": "Womens",
"category_italic": "true",
"product_name_font_color": "red"
},
{
"product_name": "Ladies Shoes",
"unit_price": 120,
"quantity": 2,
"category": "Womens",
"category_italic": "true",
"product_name_font_color": "red"
},
{
"product_name": "Belt",
"unit_price": 30,
"quantity": 2,
"category": "Accessories"
},
{
"product_name": "Bag",
"unit_price": 125,
"quantity": 4,
"category": "Accessories"
},
{
"product_name": "Mens Shoes",
"unit_price": 110,
"quantity": 2,
"category": "Mens",
"category_bold": "true",
"product_name_font_color": "blue"
},
{
"product_name": "Wallet",
"unit_price": 50,
"quantity": 2,
"category": "Accessories"
}
],
"mens_products": "<table style=\"width: 100%; border: 2px solid blue; border-collapse: collapse;\">\n <tr>\n <th style=\"border-width: 1px; border-style: solid; border-color: black; padding: 8px;\">Product Name</th>\n <th style=\"border-width: 1px; border-style: solid; border-color: black; padding: 8px;\">Unit Price</th>\n <th style=\"border-width: 1px; border-style: solid; border-color: black; padding: 8px;\">Quantity</th>\n <th style=\"border-width: 1px; border-style: solid; border-color: black; padding: 8px;\">Total Cost</th>\n </tr>\n \n <tr>\n <td style=\"border-width: 1px; border-style: solid; border-color: black; padding: 8px;\">Business Shirt</td>\n <td style=\"border-width: 1px; border-style: solid; border-color: black; padding: 8px;\">50</td>\n <td style=\"border-width: 1px; border-style: solid; border-color: black; padding: 8px;\">3</td>\n <td style=\"border-width: 1px; border-style: solid; border-color: black; padding: 8px;\">150</td>\n </tr>\n \n <tr>\n <td style=\"border-width: 1px; border-style: solid; border-color: black; padding: 8px;\">Trousers</td>\n <td style=\"border-width: 1px; border-style: solid; border-color: black; padding: 8px;\">80</td>\n <td style=\"border-width: 1px; border-style: solid; border-color: black; padding: 8px;\">3</td>\n <td style=\"border-width: 1px; border-style: solid; border-color: black; padding: 8px;\">240</td>\n </tr>\n \n <tr>\n <td style=\"border-width: 1px; border-style: solid; border-color: black; padding: 8px;\">Jacket</td>\n <td style=\"border-width: 1px; border-style: solid; border-color: black; padding: 8px;\">150</td>\n <td style=\"border-width: 1px; border-style: solid; border-color: black; padding: 8px;\">3</td>\n <td style=\"border-width: 1px; border-style: solid; border-color: black; padding: 8px;\">450</td>\n </tr>\n \n <tr>\n <td style=\"border-width: 1px; border-style: solid; border-color: black; padding: 8px;\">Mens Shoes</td>\n <td style=\"border-width: 1px; border-style: solid; border-color: black; padding: 8px;\">110</td>\n <td style=\"border-width: 1px; border-style: solid; border-color: black; padding: 8px;\">2</td>\n <td style=\"border-width: 1px; border-style: solid; border-color: black; padding: 8px;\">220</td>\n </tr>\n </table>",
"womens_products": "<table style=\"width: 100%; border: 2px solid red; border-collapse: collapse;\">\n <tr>\n <th style=\"border-width: 1px; border-style: solid; border-color: black; padding: 8px;\">Product Name</th>\n <th style=\"border-width: 1px; border-style: solid; border-color: black; padding: 8px;\">Unit Price</th>\n <th style=\"border-width: 1px; border-style: solid; border-color: black; padding: 8px;\">Quantity</th>\n <th style=\"border-width: 1px; border-style: solid; border-color: black; padding: 8px;\">Total Cost</th>\n </tr>\n \n <tr>\n <td style=\"border-width: 1px; border-style: solid; border-color: black; padding: 8px;\">Blouse</td>\n <td style=\"border-width: 1px; border-style: solid; border-color: black; padding: 8px;\">60</td>\n <td style=\"border-width: 1px; border-style: solid; border-color: black; padding: 8px;\">3</td>\n <td style=\"border-width: 1px; border-style: solid; border-color: black; padding: 8px;\">180</td>\n </tr>\n \n <tr>\n <td style=\"border-width: 1px; border-style: solid; border-color: black; padding: 8px;\">Skirt</td>\n <td style=\"border-width: 1px; border-style: solid; border-color: black; padding: 8px;\">80</td>\n <td style=\"border-width: 1px; border-style: solid; border-color: black; padding: 8px;\">3</td>\n <td style=\"border-width: 1px; border-style: solid; border-color: black; padding: 8px;\">240</td>\n </tr>\n \n <tr>\n <td style=\"border-width: 1px; border-style: solid; border-color: black; padding: 8px;\">Ladies Shoes</td>\n <td style=\"border-width: 1px; border-style: solid; border-color: black; padding: 8px;\">120</td>\n <td style=\"border-width: 1px; border-style: solid; border-color: black; padding: 8px;\">2</td>\n <td style=\"border-width: 1px; border-style: solid; border-color: black; padding: 8px;\">240</td>\n </tr>\n </table>",
"mens_total_quantity": 11,
"mens_total_cost": 1060,
"womens_total_quantity": 8,
"womens_total_cost": 660
}
]
}
]
Template
For example, we have the template with following content:
template.docx
Output
Upon processing the given data, along with transformation_function and the template, AOP generates the following result.
output.pdf
Example-II
Charts using Transformation function:
Data Source
Hereby examples of data source for different options.
- SQL
- PL/SQL returning SQL
- PL/SQL returning JSON
- JSON
select 'file1' as "filename",
cursor (
select cursor (
select cursor (
select c.cust_first_name || ' ' || c.cust_last_name as "x",
sum(o.order_total) as "y"
from aop_sample_customers c,
aop_sample_orders o
where c.customer_id = o.customer_id
group by c.cust_first_name || ' ' || c.cust_last_name
order by c.cust_first_name || ' ' || c.cust_last_name
) as "pies",
cursor (
select 'Order ' || order_id as "x",
order_total as "y"
from aop_sample_orders
) as "radars"
from dual
) as "data"
from dual
) as "data"
from dual;
declare
l_return clob;
begin
l_return := q'[
select 'file1' as "filename",
cursor (
select cursor (
select cursor (
select c.cust_first_name || ' ' || c.cust_last_name as "x",
sum(o.order_total) as "y"
from aop_sample_customers c,
aop_sample_orders o
where c.customer_id = o.customer_id
group by c.cust_first_name || ' ' || c.cust_last_name
order by c.cust_first_name || ' ' || c.cust_last_name
) as "pies",
cursor (
select 'Order ' || order_id as "x",
order_total as "y"
from aop_sample_orders
) as "radars"
from dual
) as "data"
from dual
) as "data"
from dual;
]';
return l_return;
end;
declare
l_cursor sys_refcursor;
l_return clob; -- can also be varchar2, make sure it corresponds to the structure in the JSON
begin
apex_json.initialize_clob_output(dbms_lob.call, true, 2);
open l_cursor for
select 'file1' as "filename",
cursor (
select cursor (
select cursor (
select c.cust_first_name || ' ' || c.cust_last_name as "x",
sum(o.order_total) as "y"
from aop_sample_customers c,
aop_sample_orders o
where c.customer_id = o.customer_id
group by c.cust_first_name || ' ' || c.cust_last_name
order by c.cust_first_name || ' ' || c.cust_last_name
) as "pies",
cursor (
select 'Order ' || order_id as "x",
order_total as "y"
from aop_sample_orders
) as "radars"
from dual
) as "data"
from dual
) as "data"
from dual;
apex_json.write(l_cursor);
l_return := apex_json.get_clob_output;
return l_return;
end;
[
{
"filename": "file1",
"data": {
"pies": [
{
"x": "Albert Lambert",
"y": 950
},
{
"x": "Edward Logan",
"y": 2420
},
{
"x": "Eugene Bradley",
"y": 2760
},
{
"x": "Fiorello LaGuardia",
"y": 1090
},
{
"x": "Frank OHare",
"y": 1060
},
{
"x": "John Dulles",
"y": 2380
},
{
"x": "William Hartsfield",
"y": 2370
}
],
"radars": [
{
"x": "Order 1",
"y": 1890
},
{
"x": "Order 2",
"y": 2380
},
{
"x": "Order 3",
"y": 1640
},
{
"x": "Order 4",
"y": 1090
},
{
"x": "Order 5",
"y": 950
},
{
"x": "Order 6",
"y": 1515
},
{
"x": "Order 7",
"y": 905
},
{
"x": "Order 8",
"y": 1060
},
{
"x": "Order 9",
"y": 730
},
{
"x": "Order 10",
"y": 870
}
]
}
}
]
The data ganerated from SQL is further processed by AOP when transformation function is provided. Hearby the transformation function:
- Init PL/SQL Code
- JSON
- Javascript
aop_api_pkg.g_transformation_function := 'function createRadarChart(radars) {\r\n return {\r\n type: \"radar\",\r\n name: \"Radar Chart\",\r\n options: {\r\n width: 576,\r\n height: 336,\r\n title: \"Radar Chart\",\r\n border: true,\r\n dataLabels: {\r\n showDataLabels: true,\r\n position: \"center\",\r\n showValue: true\r\n },\r\n axis: {\r\n x: {\r\n showValues: true\r\n },\r\n y: {\r\n showValues: true\r\n }\r\n }\r\n },\r\n radars: [\r\n {\r\n name: \"Orders\",\r\n data: radars\r\n }\r\n ]\r\n };\r\n}\r\n\r\nfunction createPieChart(pies) {\r\n return {\r\n type: \"pie\",\r\n name: \"Pie Chart\",\r\n options: {\r\n width: 576,\r\n height: 336,\r\n title: \"Pie Chart\",\r\n border: true,\r\n dataLabels: {\r\n showDataLabels: true,\r\n showPercentage: true\r\n }\r\n },\r\n pies: [\r\n {\r\n name: \"Customers\",\r\n data: pies\r\n }\r\n ]\r\n };\r\n}\r\n\r\nfunction transform() {\r\n files.forEach(file => {\r\n const data = file.data;\r\n if (data.radars && data.radars.length > 0) {\r\n data.radar_chart = createRadarChart(data.radars);\r\n }\r\n if (data.pies && data.pies.length > 0) {\r\n data.pie_chart = createPieChart(data.pies);\r\n }\r\n });\r\n return files;\r\n}\r\n';
"transformation_function": "function createRadarChart(radars) {\r\n return {\r\n type: \"radar\",\r\n name: \"Radar Chart\",\r\n options: {\r\n width: 576,\r\n height: 336,\r\n title: \"Radar Chart\",\r\n border: true,\r\n dataLabels: {\r\n showDataLabels: true,\r\n position: \"center\",\r\n showValue: true\r\n },\r\n axis: {\r\n x: {\r\n showValues: true\r\n },\r\n y: {\r\n showValues: true\r\n }\r\n }\r\n },\r\n radars: [\r\n {\r\n name: \"Orders\",\r\n data: radars\r\n }\r\n ]\r\n };\r\n}\r\n\r\nfunction createPieChart(pies) {\r\n return {\r\n type: \"pie\",\r\n name: \"Pie Chart\",\r\n options: {\r\n width: 576,\r\n height: 336,\r\n title: \"Pie Chart\",\r\n border: true,\r\n dataLabels: {\r\n showDataLabels: true,\r\n showPercentage: true\r\n }\r\n },\r\n pies: [\r\n {\r\n name: \"Customers\",\r\n data: pies\r\n }\r\n ]\r\n };\r\n}\r\n\r\nfunction transform() {\r\n files.forEach(file => {\r\n const data = file.data;\r\n if (data.radars && data.radars.length > 0) {\r\n data.radar_chart = createRadarChart(data.radars);\r\n }\r\n if (data.pies && data.pies.length > 0) {\r\n data.pie_chart = createPieChart(data.pies);\r\n }\r\n });\r\n return files;\r\n}\r\n"
function createRadarChart(radars) {
return {
type: "radar",
name: "Radar Chart",
options: {
width: 576,
height: 336,
title: "Radar Chart",
border: true,
dataLabels: {
showDataLabels: true,
position: "center",
showValue: true
},
axis: {
x: {
showValues: true
},
y: {
showValues: true
}
}
},
radars: [
{
name: "Orders",
data: radars
}
]
};
}
function createPieChart(pies) {
return {
type: "pie",
name: "Pie Chart",
options: {
width: 576,
height: 336,
title: "Pie Chart",
border: true,
dataLabels: {
showDataLabels: true,
showPercentage: true
}
},
pies: [
{
name: "Customers",
data: pies
}
]
};
}
function transform() {
files.forEach(file => {
const data = file.data;
if (data.radars && data.radars.length > 0) {
data.radar_chart = createRadarChart(data.radars);
}
if (data.pies && data.pies.length > 0) {
data.pie_chart = createPieChart(data.pies);
}
});
return files;
}
AOP executes the transformation_function
internally that gives the following modified data:
- JSON
[
{
"filename": "file1",
"data": {
"pies": [
{
"x": "Albert Lambert",
"y": 950
},
{
"x": "Edward Logan",
"y": 2420
},
{
"x": "Eugene Bradley",
"y": 2760
},
{
"x": "Fiorello LaGuardia",
"y": 1090
},
{
"x": "Frank OHare",
"y": 1060
},
{
"x": "John Dulles",
"y": 2380
},
{
"x": "William Hartsfield",
"y": 2370
}
],
"radars": [
{
"x": "Order 1",
"y": 1890
},
{
"x": "Order 2",
"y": 2380
},
{
"x": "Order 3",
"y": 1640
},
{
"x": "Order 4",
"y": 1090
},
{
"x": "Order 5",
"y": 950
},
{
"x": "Order 6",
"y": 1515
},
{
"x": "Order 7",
"y": 905
},
{
"x": "Order 8",
"y": 1060
},
{
"x": "Order 9",
"y": 730
},
{
"x": "Order 10",
"y": 870
}
],
"radar_chart": {
"type": "radar",
"name": "Radar Chart",
"options": {
"width": 576,
"height": 336,
"title": "Radar Chart",
"border": true,
"dataLabels": {
"showDataLabels": true,
"position": "center",
"showValue": true
},
"axis": {
"x": {
"showValues": true
},
"y": {
"showValues": true
}
}
},
"radars": [
{
"name": "Orders",
"data": [
{
"x": "Order 1",
"y": 1890
},
{
"x": "Order 2",
"y": 2380
},
{
"x": "Order 3",
"y": 1640
},
{
"x": "Order 4",
"y": 1090
},
{
"x": "Order 5",
"y": 950
},
{
"x": "Order 6",
"y": 1515
},
{
"x": "Order 7",
"y": 905
},
{
"x": "Order 8",
"y": 1060
},
{
"x": "Order 9",
"y": 730
},
{
"x": "Order 10",
"y": 870
}
]
}
]
},
"pie_chart": {
"type": "pie",
"name": "Pie Chart",
"options": {
"width": 576,
"height": 336,
"title": "Pie Chart",
"border": true,
"dataLabels": {
"showDataLabels": true,
"showPercentage": true
}
},
"pies": [
{
"name": "Customers",
"data": [
{
"x": "Albert Lambert",
"y": 950
},
{
"x": "Edward Logan",
"y": 2420
},
{
"x": "Eugene Bradley",
"y": 2760
},
{
"x": "Fiorello LaGuardia",
"y": 1090
},
{
"x": "Frank OHare",
"y": 1060
},
{
"x": "John Dulles",
"y": 2380
},
{
"x": "William Hartsfield",
"y": 2370
}
]
}
]
}
}
}
]
Template
For example, we have the template with following content:
template.docx
Output
Upon processing the given data, along with transformation_function and the template, AOP generates the following result.
output.pdf
Example III (using file)
Available From: v25.1You can also specify filename in the transformation function
. Suppose there a file in AOP Directory > assets > transformation_functions > sample_transform.js
.
Using the Init PL/SQL, you can provide the transformation function that references a file as:
- Init PL/SQL Code
- JSON
- Javascript Function in the file sample_html_transform.js
aop_api_pkg.g_transformation_function := 'sample_transform.js';
"transformation_function": "sample_transform.js"
function transform() {
files.forEach(file => {
file.data.forEach(data => {
// Manipulation of data
});
});
return files;
}
You can manually add the files in the AOP Directory > assets > transformation_functions, and provide the filename (with .js extension) in the transformation_function
.
- While providing the filename in
transformation_function
, .js extension is mandatory. - The file outside the AOP Directory > assets > transformation_functions is not accessible.
Data Source, Template and Output
The data source, template and output is same as of Example 1
Providing the file name instead of whole transformation function simplifies the transformation function usage and reduces the payload for the request to AOP. Also, you can use same file in the multiple requests.