Iframes allow you to insert widgets from other websites (for example, a map from Google Maps) and arbitrary HTML markup with JavaScript support (for example, to display charts written using d3js).
iframes can be displayed on forms as additional information or can be combined with multiple graphs in a dashboard.
Examples:
To add an iframe in a request for a cell, you need to specify the control = 'iframe'
attributes, as well as a link to the iframe itself in one of the following ways:
iframe_markup
specify the scheme and the name of the markup from the markup tableiframe_src
- specify a link to the website that will be opened in iframeiframe_srcdoc
- specify HTML layout codeiframe_markup_name
- specify markup name from markup tableExample (admin.pie_chart
implementation will be shown bellow in the next block):
WITH data AS (
SELECT COUNT(id) as cnt, status.@text as status
FROM pm.tasks
WHERE NOT is_archived
GROUP BY status
ORDER BY status
)
SELECT
@type = 'form',
@title = 'Tasks by Statuses' || COALESCE(': ' || (SELECT string_agg(value.@text, ', ') FROM DOMAIN OF FIELD pm.tasks.status as statuses WHERE value = ANY($status)), ''),
@block_sizes = array[ 12 ],
(
SELECT {
data: json_agg({
label: data.status,
value: data.cnt
}),
color: ['#EE0164','#FFBC5C', '#068274', '#415157','#589C03'],
donut_ratio: 0,
label_type: 'percent'
}
FROM data
) as value @{
control = 'iframe',
iframe_markup = {
schema: 'admin',
name: 'pie_chart'
},
caption = ' ',
form_block = 0,
control_height = 300
}
The value of the cell in the request (value
in this case) is passed to the iframe.
But in some cases there is no need to provide data to the iframe.
For example, in the case of a map, you can write:
SELECT
@type = 'form',
@block_sizes = [ 12 ],
null as map @{
control = 'iframe',
form_block = 0,
iframe_markup = {
schema: 'demo',
name: 'map'
},
caption = 'Demo map',
}
Each instance has a funapp.iframe_markups
table in which it is recommended to store markups for iframes.
The markup for the iframe is the usual HTML layout, with the ability to include styles and third-party JS scripts.
Below you can see an example of implementing a pie chart using a third-party library nv.d3.js
<html style="height: 100%; width: 100%; margin: 0;">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.1.15-beta/nv.d3.min.css">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.1.15-beta/nv.d3.min.js"></script>
<script src="https://ozma.io/ozma-embedded.min.js"></script>
</head>
<body onclick="FunApp.linkClick(event)" style="height: 100%; width: 100%; margin: 0; overflow: auto; position: relative; ">
<div id="chart"><svg></svg></div>
<style>
body {
background-color: white;
}
#chart svg {
height: 300px;
}
.nv-label text{
font-family: Droid Sans;
}
.nvd3.nv-noData {
font: italic 1em "Fira Sans", sans-serif;
}
</style>
<script>
/* currentValue.value = {
data: [{ "label": "One", "value" : 29.765957771107 }, { "label": "Two", "value" : 0}],
color: ['#ff7f0e','#2ca02c','#d62728','#9467bd','#8c564b','#e377c2','#7f7f7f','#bcbd22','#17becf'],
donut_ration: 0
} */
FunApp.addValueHandler(currentValue => {
const event_data = currentValue.value;
const data = event_data.data ?? [];
const color = event_data.color ?? d3.scale.category10().range().slice(1);
const donutRatio = event_data.donut_ratio ?? 0;
const labelType = event_data.label_type ?? "percent";
const svgElem = document.getElementsByTagName('svg')[0];
const margin = { left: 0, right: 0, top: 2, bottom: 2},
width = svgElem.clientWidth - margin.left - margin.right,
height = svgElem.clientHeight - margin.top - margin.bottom;
nv.addGraph(function() {
var chart = nv.models.pieChart()
.x(function(d) { return d.label })
.y(function(d) { return d.value })
.color(color)
.showLabels(true)
.labelThreshold(.05)
.labelType(labelType)
.donut(true)
.donutRatio(donutRatio);
a = d3.select("#chart svg")
.attr("width", width)
.datum(data)
.transition()
.duration(1200)
.call(chart);
console.log(a)
return chart;
});
});
</script>
</body>
</html>
To get data inside an iframe from a FunQL query, you need to add a handler:
<script src="https://ozma.io/ozma-embedded.min.js"></script>
body
tag add the event onclick="FunApp.linkClick(event)"
script
FunApp.addValueHandler(currentValue => { ...})