@opengis/bi 1.0.39 → 1.0.41

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,61 +1,65 @@
1
- function normalizeData(data, query = {}, columnTypes = []) {
2
- const skip = [];
3
- ['x', 'groupby', 'granularity'].forEach((el) => {
4
- // console.log(el, query[el], columnTypes.find(col => col.name == query[el]))
5
- if (!columnTypes.find((col) => col.name == query[el])) {
6
- if (query[el] && query[el] !== 'null') skip.push(`column not found: ${query[el]}`);
7
- if (!(el === 'groupby' && query[el] === 'null')) delete query[el];
8
- }
9
- });
10
-
11
- if (
12
- !columnTypes.find(
13
- (col) => col.type === 'numeric' && col.name == query.metric
14
- )
15
- ) {
16
- delete query.metric;
17
- }
18
-
19
- const xName = query.x || (Array.isArray(data.x) ? data.x[0] : data.x);
20
- const xType = columnTypes.find((el) => el.name == xName)?.type;
21
-
22
- const granularity =
23
- xType === 'date' || xType?.includes('timestamp')
24
- ? query.granularity || data.granularity || 'year'
25
- : null;
26
-
27
- const x =
28
- (granularity
29
- ? `date_trunc('${granularity}',${xName})::date::text`
30
- : null) || xName;
31
-
32
- const metrics = Array.isArray(data.metrics || data.metric) ? (data.metrics || data.metric) : [data.metrics || data.metric];
33
- const metric =
34
- (query.metric ? `sum(${query.metric})` : null) ||
35
- (metrics.length
36
- ? (metrics
37
- ?.filter((el) => el && columnTypes.find((col) => col.name == (el?.name || el)))
38
- ?.map((el) => el.fx || `${el.operator || 'sum'}(${el.name || el})`)?.join(',') || 'count(*)')
39
- : 'count(*)');
40
-
41
- const yName = metrics?.[0]?.name || metrics?.[0];
42
- const yType = columnTypes.find((el) => el.name == yName)?.type;
43
-
44
- const { cls, table, filterCustom } = data;
45
- const groupby = (query.groupby || data.groupby) === 'null' ? null : (query.groupby || data.groupby);
46
- // const orderby = query.orderby || data.orderby || 'count(*)';
47
-
48
- const custom = query?.filterCustom
49
- ?.split(',')
50
- ?.map((el) => filterCustom?.find((item) => item?.name === el)?.sql)
51
- ?.filter((el) => el)
52
- ?.join(' and ');
53
- const where = `${data.query || '1=1'} and ${custom || 'true'}`;
54
-
55
- const tableSQL = data.tableSQL?.length
56
- ? `(select * from ${data?.table} t ${data.tableSQL.join(' \n ')} where ${where})q`
57
- : undefined;
58
-
59
- return { x, cls, metric, table, where, tableSQL, groupby, xName, xType, yName, yType, error: skip.length ? skip.join(',') : undefined };
60
- }
61
- export default normalizeData;
1
+ function normalizeData(data, query = {}, columnTypes = []) {
2
+ const skip = [];
3
+ ['x', 'groupby', 'granularity'].forEach((el) => {
4
+ // console.log(el, query[el], columnTypes.find(col => col.name == query[el]))
5
+ if (!columnTypes.find((col) => col.name == query[el])) {
6
+ if (query[el] && query[el] !== 'null') {
7
+ if (el === 'granularity' && !['week', 'month', 'quarter', 'year'].includes(query[el])) {
8
+ skip.push(`invalid granularity option: ${query[el]}`);
9
+ } else if (el !== 'granularity') { skip.push(`column not found: ${query[el]}`); }
10
+ }
11
+ if (!(el === 'granularity' || (el === 'groupby' && query[el] === 'null'))) delete query[el];
12
+ }
13
+ });
14
+
15
+ if (
16
+ !columnTypes.find(
17
+ (col) => col.type === 'numeric' && col.name == query.metric
18
+ )
19
+ ) {
20
+ delete query.metric;
21
+ }
22
+
23
+ const xName = query.x || (Array.isArray(data.x) ? data.x[0] : data.x);
24
+ const xType = columnTypes.find((el) => el.name == xName)?.type;
25
+
26
+ const granularity =
27
+ xType === 'date' || xType?.includes('timestamp')
28
+ ? query.granularity || data.granularity || 'year'
29
+ : null;
30
+
31
+ const x =
32
+ (granularity
33
+ ? `date_trunc('${granularity}',${xName})::date::text`
34
+ : null) || xName;
35
+
36
+ const metrics = Array.isArray(data.metrics || data.metric) ? (data.metrics || data.metric) : [data.metrics || data.metric];
37
+ const metric =
38
+ (query.metric ? `sum(${query.metric})` : null) ||
39
+ (metrics.length
40
+ ? (metrics
41
+ ?.filter((el) => el && columnTypes.find((col) => col.name == (el?.name || el)))
42
+ ?.map((el) => el.fx || `${el.operator || 'sum'}(${el.name || el})`)?.join(',') || 'count(*)')
43
+ : 'count(*)');
44
+
45
+ const yName = metrics?.[0]?.name || metrics?.[0];
46
+ const yType = columnTypes.find((el) => el.name == yName)?.type;
47
+
48
+ const { cls, table, filterCustom } = data;
49
+ const groupby = (query.groupby || data.groupby) === 'null' ? null : (query.groupby || data.groupby);
50
+ // const orderby = query.orderby || data.orderby || 'count(*)';
51
+
52
+ const custom = query?.filterCustom
53
+ ?.split(',')
54
+ ?.map((el) => filterCustom?.find((item) => item?.name === el)?.sql)
55
+ ?.filter((el) => el)
56
+ ?.join(' and ');
57
+ const where = `${data.query || '1=1'} and ${custom || 'true'}`;
58
+
59
+ const tableSQL = data.tableSQL?.length
60
+ ? `(select * from ${data?.table} t ${data.tableSQL.join(' \n ')} where ${where})q`
61
+ : undefined;
62
+
63
+ return { x, cls, metric, table, where, tableSQL, groupby, xName, xType, yName, yType, error: skip.length ? skip.join(',') : undefined };
64
+ }
65
+ export default normalizeData;
@@ -1,4 +1,4 @@
1
- import { pgClients, getFilterSQL } from '@opengis/fastify-table/utils.js';
1
+ import { pgClients, getFilterSQL, getSelectVal } from '@opengis/fastify-table/utils.js';
2
2
 
3
3
  import { getWidget } from '../../../../utils.js';
4
4
 
@@ -29,6 +29,12 @@ export default async function map(req) {
29
29
  const { rows = [] } = await pg.query(
30
30
  `select count(*), "${data.color}" as val from ${data.table} where ${data.query || '1=1'} group by "${data.color}"`
31
31
  );
32
+ if (data?.cls) {
33
+ const vals = await getSelectVal({
34
+ pg, name: data.cls, values: rows.map(el => el.val),
35
+ });
36
+ rows.forEach(row => Object.assign(row, { val: vals?.[row.val || ''] || row.val }));
37
+ }
32
38
  Object.assign(res, { colors: rows }); // кольори для легенди
33
39
  }
34
40
  if (data?.metrics?.length) {
@@ -40,13 +46,13 @@ export default async function map(req) {
40
46
  PERCENTILE_CONT(1) WITHIN GROUP (ORDER BY "${metric}") as "100" from ${data.table} where ${data.query || '1=1'} and ${q || '1=1'}`;
41
47
  const sizes = await pg
42
48
  .query(q1)
43
- .then((res1) => Object.values(res1.rows?.[0] || {}));
49
+ .then(el => Object.values(el.rows?.[0] || {}));
44
50
  Object.assign(res, { sizes }); // розміри для легенди
45
51
  }
46
52
  const { bounds, extentStr } = await pg.query(`select count(*),
47
53
  st_asgeojson(st_extent(geom))::json as bounds,
48
54
  replace(regexp_replace(st_extent(geom)::box2d::text,'BOX\\(|\\)','','g'),' ',',') as "extentStr"
49
- from ${data.table} where ${data.query || '1=1'}`).then((res) => res.rows?.[0] || {});
55
+ from ${data.table} where ${data.query || '1=1'}`).then(el => el.rows?.[0] || {});
50
56
  const extent = extentStr ? extentStr.split(',') : undefined;
51
57
 
52
58
  Object.assign(res, {
@@ -1,79 +0,0 @@
1
- import { l as M, m as w } from "./map-component-mixin-C1bMsX3E.js";
2
- import { _ as b, c as y } from "./import-file-DXZLuS8B.js";
3
- import { resolveComponent as i, createElementBlock as V, openBlock as u, createElementVNode as d, createBlock as _, createCommentVNode as v, createVNode as c } from "vue";
4
- const $ = {
5
- mixins: [y, M, w],
6
- name: "VsMap",
7
- async mounted() {
8
- await this.getMapData(), await this.createMap();
9
- },
10
- methods: {
11
- async getMapData() {
12
- const s = await (await fetch(
13
- `/api/bi-map?widget=${this.widget}&dashboard=${this.dashboard}`
14
- )).json();
15
- this.data = s;
16
- },
17
- async loadHandler() {
18
- const a = ["#69D2E7", "yellow", "#FE4365"], s = this.data.colors ? ["match", ["get", "x"]].concat(
19
- this.data.colors.reduce(
20
- (o, t, r) => o.concat(t.val, a[r]),
21
- []
22
- )
23
- ).concat(["gray"]) : "blue", p = [5, 7, 9, 11, 13], e = this.data.sizes ? ["case"] : 5;
24
- this.data.sizes && (this.data.sizes.reverse().forEach((o, t) => {
25
- e.push([">", ["get", "metric"], o]), e.push(p[t]);
26
- }), e.push(5));
27
- const n = {
28
- type: "circle",
29
- color: s,
30
- width: 2,
31
- radius: e,
32
- stroke: "#eee"
33
- };
34
- Object.assign(n, this.data.style || {}), this.addVtileLayer({
35
- id: "bi",
36
- url: `${window.top.location.origin}/api/bi-vtile/{z}/{x}/{y}.vmt?widget=${this.widget}&dashboard=${this.dashboard}&nocache=1`,
37
- style: n
38
- });
39
- }
40
- }
41
- }, z = ["id"], I = ["id"], k = { ref: "popup" }, x = { class: "absolute flex flex-col right-[10px] top-[105px] gap-1" };
42
- function E(a, s, p, e, n, o) {
43
- var l, m, h;
44
- const t = i("VsMapSetting"), r = i("VsMapSlotLayers"), f = i("VsMapLegend"), g = i("VsMapGoHome");
45
- return u(), V("div", {
46
- class: "relative w-full h-full",
47
- id: `wrapper-${a.mapId}`
48
- }, [
49
- d("div", {
50
- id: a.mapId,
51
- class: "w-full flex items-end relative h-[250px]"
52
- }, [
53
- d("div", k, null, 512)
54
- ], 8, I),
55
- a.showSetting ? (u(), _(t, {
56
- key: 0,
57
- map: a.map,
58
- coordinates: a.coordinatesByMouse
59
- }, null, 8, ["map", "coordinates"])) : v("", !0),
60
- c(r, { map: a.map }, null, 8, ["map"]),
61
- d("div", x, [
62
- c(f, {
63
- mapId: a.mapId,
64
- colors: (l = a.data) == null ? void 0 : l.colors,
65
- sizes: (m = a.data) == null ? void 0 : m.sizes,
66
- color: a.color,
67
- resizeItem: "true"
68
- }, null, 8, ["mapId", "colors", "sizes", "color"]),
69
- c(g, {
70
- map: a.map,
71
- bbox: (h = a.data) == null ? void 0 : h.bounds
72
- }, null, 8, ["map", "bbox"])
73
- ])
74
- ], 8, z);
75
- }
76
- const C = /* @__PURE__ */ b($, [["render", E]]);
77
- export {
78
- C as default
79
- };
@@ -1,104 +0,0 @@
1
- import { l as v, m as k, p as L } from "./map-component-mixin-C1bMsX3E.js";
2
- import { _ as C, c as I } from "./import-file-DXZLuS8B.js";
3
- import { resolveComponent as e, createElementBlock as S, openBlock as g, createElementVNode as u, createBlock as _, createCommentVNode as $, createVNode as i } from "vue";
4
- const z = {
5
- mixins: [I, v, k],
6
- data() {
7
- return {
8
- baseColor: "pink",
9
- kattotg: ""
10
- };
11
- },
12
- async mounted() {
13
- await this.getMapData(), await this.createMap();
14
- },
15
- watch: {
16
- kattotg() {
17
- this.loadHandler();
18
- }
19
- },
20
- methods: {
21
- async getMapData() {
22
- const t = await fetch(
23
- `/api/bi-cluster?widget=${this.widget}&dashboard=${this.dashboard}`
24
- );
25
- this.data = await t.json();
26
- },
27
- async loadHandler() {
28
- var r;
29
- this.baseColor = ((r = this.data.style) == null ? void 0 : r.color) || "blue";
30
- const t = ["case"];
31
- this.data.sizes.reverse().forEach((s, n) => {
32
- t.push([">", ["get", "metric"], s]), t.push(L[this.baseColor][n]), n++;
33
- }), t.push("gray");
34
- const a = {
35
- type: "polygon",
36
- color: t,
37
- opacity: 0.4
38
- };
39
- Object.assign(a, this.data.style || {}), this.map.getSource("bi") || this.addVtileLayer({
40
- id: "bi",
41
- url: `${window.location.origin}/api/bi-cluster-vtile/{z}/{x}/{y}.vmt?widget=${this.widget}&dashboard=${this.dashboard}&nocache=1`,
42
- style: a
43
- }), this.map.getLayer("highlighted") && this.map.removeLayer("highlighted"), this.map.getSource("highlighted") && this.map.removeSource("highlighted");
44
- const o = ["case"];
45
- this.kattotg && o.push(
46
- ["==", ["to-string", ["get", "name"]], String(this.kattotg)],
47
- "red"
48
- ), o.push("transparent"), this.map.addLayer({
49
- id: "highlighted",
50
- type: "fill",
51
- source: "bi",
52
- "source-layer": "bi",
53
- paint: {
54
- "fill-color": o,
55
- "fill-opacity": 0.6
56
- }
57
- });
58
- }
59
- }
60
- }, B = ["id"], H = ["id"], E = { class: "absolute flex flex-col right-[10px] top-[105px] gap-1" };
61
- function N(t, a, o, r, s, n) {
62
- var l, p, d, c, h, m;
63
- const y = e("VsMapSetting"), f = e("VsMapSlotLayers"), b = e("VsMapLegend"), w = e("VsMapGoHome"), M = e("VsList");
64
- return g(), S("div", {
65
- class: "relative w-full h-full",
66
- id: `wrapper-${t.mapId}`
67
- }, [
68
- u("div", {
69
- id: t.mapId,
70
- class: "h-[96%] w-full flex items-end min-h-[250px]"
71
- }, null, 8, H),
72
- t.showSetting ? (g(), _(y, {
73
- key: 0,
74
- map: t.map,
75
- coordinates: t.coordinatesByMouse
76
- }, null, 8, ["map", "coordinates"])) : $("", !0),
77
- i(f, { map: t.map }, null, 8, ["map"]),
78
- u("div", E, [
79
- i(b, {
80
- mapId: t.mapId,
81
- colors: (l = t.data) == null ? void 0 : l.colors,
82
- sizes: (p = t.data) == null ? void 0 : p.sizes,
83
- color: s.baseColor,
84
- changeOpacityItem: "true",
85
- cluster: "true"
86
- }, null, 8, ["mapId", "colors", "sizes", "color"]),
87
- i(w, {
88
- map: t.map,
89
- bbox: (d = t.data) == null ? void 0 : d.bounds
90
- }, null, 8, ["map", "bbox"]),
91
- i(M, {
92
- mapId: t.mapId,
93
- source: (c = t.data) == null ? void 0 : c.rows,
94
- total: ((h = t.data) == null ? void 0 : h.total) || 0,
95
- count: ((m = t.data) == null ? void 0 : m.count) || 0,
96
- onKattotg: a[0] || (a[0] = (V) => s.kattotg = V)
97
- }, null, 8, ["mapId", "source", "total", "count"])
98
- ])
99
- ], 8, B);
100
- }
101
- const O = /* @__PURE__ */ C(z, [["render", N]]);
102
- export {
103
- O as default
104
- };