@opengis/bi
Version:
BI data visualization module
70 lines (62 loc) • 2.72 kB
JavaScript
import { pgClients, getFilterSQL, getSelectVal } from '@opengis/fastify-table/utils.js';
import { getWidget } from '../../../../utils.js';
export default async function map(req) {
const { query = {} } = req;
const { dashboard, widget } = query;
const { pg = req.pg || pgClients.client, data, type, layers, style, controls } = await getWidget({ pg: req.pg, dashboard, widget });
if (!['map'].includes(type)) {
return { message: 'access restricted: invalid widget type', status: 403 };
}
if (!data?.table) {
return { message: 'invalid widget: param table is required', status: 400 };
}
if (!pg.pk[data?.table]) {
return { message: 'invalid widget: table pkey not found', status: 400 };
}
const { q = '' } = await getFilterSQL({
pg,
table: data?.table,
filter: query.filter,
});
const res = {};
if (data?.color) {
const { rows = [] } = await pg.query(
`select count(*), "${data.color}" as val from ${data.table} where ${data.query || '1=1'} group by "${data.color}"`
);
if (data?.cls) {
const vals = await getSelectVal({
pg, name: data.cls, values: rows.map(el => el.val), ar: true,
});
rows.forEach(row => Object.assign(row, { ...vals?.find?.(el => el.id === row.val) || { text: row.val } }));
}
Object.assign(res, { colors: rows }); // кольори для легенди
}
if (data?.metrics?.length) {
const metric = data?.metrics[0];
const q1 = `select PERCENTILE_CONT(0) WITHIN GROUP (ORDER BY "${metric}") as "0",
PERCENTILE_CONT(0.25) WITHIN GROUP (ORDER BY "${metric}") as "25",
PERCENTILE_CONT(0.50) WITHIN GROUP (ORDER BY "${metric}") as "50",
PERCENTILE_CONT(0.75) WITHIN GROUP (ORDER BY "${metric}") as "75",
PERCENTILE_CONT(1) WITHIN GROUP (ORDER BY "${metric}") as "100" from ${data.table} where ${data.query || '1=1'} and ${q || '1=1'}`;
const sizes = await pg
.query(q1)
.then(el => Object.values(el.rows?.[0] || {}));
Object.assign(res, { sizes }); // розміри для легенди
}
const { bounds, extentStr } = await pg.query(`select count(*),
st_asgeojson(st_extent(geom))::json as bounds,
replace(regexp_replace(st_extent(geom)::box2d::text,'BOX\\(|\\)','','g'),' ',',') as "extentStr"
from ${data.table} where ${data.query || '1=1'}`).then(el => el.rows?.[0] || {});
const extent = extentStr ? extentStr.split(',') : undefined;
Object.assign(res, {
layers,
style,
controls,
columns: data.columns,
bounds, // Map bounds
extent,
top: [], // 10 найкращих
bottom: [], // 10 найгірших
});
return res;
}