@opengis/bi 1.0.11 → 1.0.12

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.
Files changed (88) hide show
  1. package/dist/assets/charts/bar.png +0 -0
  2. package/dist/assets/charts/funnel.png +0 -0
  3. package/dist/assets/charts/no_data.jpg +0 -0
  4. package/dist/assets/charts/number.png +0 -0
  5. package/dist/assets/charts/pie.png +0 -0
  6. package/dist/assets/charts/progress.png +0 -0
  7. package/dist/assets/charts/stat.png +0 -0
  8. package/dist/assets/images/bar.png +0 -0
  9. package/dist/assets/images/funnel.png +0 -0
  10. package/dist/assets/images/no_data.jpg +0 -0
  11. package/dist/assets/images/number.png +0 -0
  12. package/dist/assets/images/pie.png +0 -0
  13. package/dist/assets/images/progress.png +0 -0
  14. package/dist/assets/images/stat.png +0 -0
  15. package/dist/bi.js +1 -1
  16. package/dist/bi.umd.cjs +723 -113
  17. package/dist/{import-file-D6RYWvi_.js → import-file-Db7C78fp.js} +43157 -43204
  18. package/dist/style.css +1 -1
  19. package/dist/vs-calendar-Ddl6WRL3.js +96 -0
  20. package/dist/vs-funnel-bar-GbisTylf.js +92 -0
  21. package/dist/vs-heatmap-CPiim0yg.js +83 -0
  22. package/dist/vs-map-DuBKvlTI.js +19422 -0
  23. package/dist/vs-number-CR1H0JTM.js +39 -0
  24. package/dist/{vs-text-UyIWGqQO.js → vs-text-C3RkizPQ.js} +60 -60
  25. package/package.json +7 -5
  26. package/server/routes/dashboard/controllers/dashboard.js +20 -1
  27. package/server/routes/data/controllers/data.js +31 -19
  28. package/server/routes/data/controllers/util/chartSQL.js +8 -7
  29. package/server/routes/data/controllers/util/normalizeData.js +10 -4
  30. package/server/routes/edit/controllers/dashboard.add.js +5 -1
  31. package/server/routes/edit/controllers/dashboard.edit.js +5 -1
  32. package/server/routes/edit/controllers/widget.add.js +23 -7
  33. package/server/routes/edit/controllers/widget.del.js +1 -1
  34. package/server/routes/edit/controllers/widget.edit.js +8 -5
  35. package/server/routes/map/controllers/cluster.js +90 -0
  36. package/server/routes/map/controllers/clusterVtile.js +144 -0
  37. package/server/routes/map/controllers/geojson.js +1 -1
  38. package/server/routes/map/controllers/map.js +63 -0
  39. package/server/routes/map/controllers/vtile.js +1 -1
  40. package/server/routes/map/index.mjs +7 -4
  41. package/server/templates/cls/demo.parcel.object_type.json +12 -0
  42. package/server/templates/dashboard/demo/funnel.yml +18 -0
  43. package/server/templates/dashboard/demo/heatmap.yml +18 -0
  44. package/server/templates/dashboard/demo/index.yml +58 -0
  45. package/server/templates/dashboard/demo/line.yml +19 -0
  46. package/server/templates/dashboard/demo/map.yml +13 -0
  47. package/server/templates/dashboard/demo/pivot.yml +18 -0
  48. package/server/templates/dashboard/demo/progress.yml +15 -0
  49. package/server/templates/dashboard/demo/quarterly_revenue.yml +17 -0
  50. package/server/templates/dashboard/demo/quarterly_revenue_by_product_line.yml +19 -0
  51. package/server/templates/dashboard/demo/stat.yml +15 -0
  52. package/server/templates/dashboard/demo/total_products_sold.yml +9 -0
  53. package/server/templates/dashboard/demo/total_products_sold_by_product_line.yml +12 -0
  54. package/server/templates/dashboard/demo/total_revenue.yml +10 -0
  55. package/server/templates/dashboard/demo/total_revenue_by_product_line.yml +20 -0
  56. package/server/templates/dashboard/demo/vehicle_sales_info.md +17 -0
  57. package/server/templates/dashboard/demo/waterfall.yml +19 -0
  58. package/server/templates/dashboard/erobota/bar_area.yml +3 -1
  59. package/server/templates/dashboard/erobota/bar_culture.yml +1 -1
  60. package/server/templates/dashboard/erobota/bar_grand.yml +3 -2
  61. package/server/templates/dashboard/erobota/count_grand.yml +1 -1
  62. package/server/templates/dashboard/erobota/index.yml +14 -12
  63. package/server/templates/dashboard/erobota/list_culture.yml +1 -1
  64. package/server/templates/dashboard/erobota/list_grant.yml +1 -1
  65. package/server/templates/dashboard/erobota/map.yml +1 -1
  66. package/server/templates/dashboard/erobota/pie_area.yml +1 -1
  67. package/server/templates/dashboard/erobota/pie_grant.yml +1 -1
  68. package/server/templates/dashboard/erobota/total_area.yml +1 -1
  69. package/server/templates/dashboard/erobota/total_grand.yml +1 -1
  70. package/server/templates/dashboard/map/index.yml +6 -0
  71. package/server/templates/dashboard/map/map.yml +13 -0
  72. package/server/templates/dashboard/map/mapCluster.yml +16 -0
  73. package/server/templates/dashboard/sales/index.yml +4 -3
  74. package/server/templates/dashboard/sales/quarterly_revenue.yml +1 -3
  75. package/server/templates/dashboard/sales/quarterly_revenue_by_product_line.yml +1 -1
  76. package/server/templates/dashboard/sales/total_products_sold.yml +1 -1
  77. package/server/templates/dashboard/sales/total_products_sold_by_product_line.yml +2 -1
  78. package/server/templates/dashboard/sales/total_revenue.yml +1 -1
  79. package/server/templates/dashboard/sales/total_revenue_by_product_line.yml +4 -1
  80. package/server/templates/dashboard/test3/quarterly_revenue.yml +1 -1
  81. package/server/templates/dashboard/test3/widget1.yml +1 -1
  82. package/server/templates/widget/calendar.yml +14 -0
  83. package/server/templates/widget/map.yml +15 -0
  84. package/server/templates/widget/mapCluster.yml +16 -0
  85. package/server/templates/widget/negative.yml +18 -0
  86. package/server/templates/widget/negative_profi_expense.yml +23 -0
  87. package/server/templates/widget/negative_type.yml +24 -0
  88. package/dist/vs-number-DKF5ptAP.js +0 -34
@@ -0,0 +1,39 @@
1
+ import { _ as s, c as i, f as o } from "./import-file-Db7C78fp.js";
2
+ import { openBlock as c, createElementBlock as n, toDisplayString as a } from "vue";
3
+ const m = {
4
+ mixins: [i],
5
+ data() {
6
+ return {
7
+ number: ""
8
+ };
9
+ },
10
+ computed: {
11
+ formattedNumber() {
12
+ return o(this.number);
13
+ },
14
+ prefix() {
15
+ var t, e;
16
+ return (t = this.styleData) != null && t.prefix ? (e = this.styleData) == null ? void 0 : e.prefix : "";
17
+ }
18
+ },
19
+ async mounted() {
20
+ await this.getData(), this.getNumber();
21
+ },
22
+ methods: {
23
+ async getNumber() {
24
+ var t;
25
+ try {
26
+ this.number = this.sourceData[0][Object.keys((t = this.sourceData) == null ? void 0 : t[0])];
27
+ } catch (e) {
28
+ console.error(e);
29
+ }
30
+ }
31
+ }
32
+ }, u = { class: "font-[Inter,_Helvetica,_Arial] p-4 w-full text-[28px] pt-[10px] min-h-[130px] border-0" };
33
+ function p(t, e, f, h, d, r) {
34
+ return c(), n("div", u, a(r.prefix) + a(r.formattedNumber), 1);
35
+ }
36
+ const _ = /* @__PURE__ */ s(m, [["render", p]]);
37
+ export {
38
+ _ as default
39
+ };
@@ -1,9 +1,9 @@
1
1
  var ge = Object.defineProperty;
2
2
  var ke = (c, e, t) => e in c ? ge(c, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : c[e] = t;
3
3
  var k = (c, e, t) => ke(c, typeof e != "symbol" ? e + "" : e, t);
4
- import { openBlock as V, createElementBlock as J, createCommentVNode as de } from "vue";
5
- import { _ as xe } from "./import-file-D6RYWvi_.js";
6
- function j() {
4
+ import { _ as de, c as xe } from "./import-file-Db7C78fp.js";
5
+ import { openBlock as V, createElementBlock as J, createCommentVNode as be } from "vue";
6
+ function D() {
7
7
  return {
8
8
  async: !1,
9
9
  breaks: !1,
@@ -17,33 +17,33 @@ function j() {
17
17
  walkTokens: null
18
18
  };
19
19
  }
20
- let z = j();
20
+ let z = D();
21
21
  function se(c) {
22
22
  z = c;
23
23
  }
24
- const ie = /[&<>"']/, be = new RegExp(ie.source, "g"), re = /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/, me = new RegExp(re.source, "g"), we = {
24
+ const ie = /[&<>"']/, me = new RegExp(ie.source, "g"), re = /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/, we = new RegExp(re.source, "g"), ye = {
25
25
  "&": "&amp;",
26
26
  "<": "&lt;",
27
27
  ">": "&gt;",
28
28
  '"': "&quot;",
29
29
  "'": "&#39;"
30
- }, K = (c) => we[c];
30
+ }, K = (c) => ye[c];
31
31
  function b(c, e) {
32
32
  if (e) {
33
33
  if (ie.test(c))
34
- return c.replace(be, K);
34
+ return c.replace(me, K);
35
35
  } else if (re.test(c))
36
- return c.replace(me, K);
36
+ return c.replace(we, K);
37
37
  return c;
38
38
  }
39
- const ye = /(^|[^\[])\^/g;
39
+ const $e = /(^|[^\[])\^/g;
40
40
  function f(c, e) {
41
41
  let t = typeof c == "string" ? c : c.source;
42
42
  e = e || "";
43
43
  const n = {
44
44
  replace: (s, i) => {
45
45
  let r = typeof i == "string" ? i : i.source;
46
- return r = r.replace(ye, "$1"), t = t.replace(s, r), n;
46
+ return r = r.replace($e, "$1"), t = t.replace(s, r), n;
47
47
  },
48
48
  getRegex: () => new RegExp(t, e)
49
49
  };
@@ -92,7 +92,7 @@ function _(c, e, t) {
92
92
  }
93
93
  return c.slice(0, n - s);
94
94
  }
95
- function $e(c, e) {
95
+ function Te(c, e) {
96
96
  if (c.indexOf(e[1]) === -1)
97
97
  return -1;
98
98
  let t = 0;
@@ -127,7 +127,7 @@ function te(c, e, t, n) {
127
127
  text: b(r)
128
128
  };
129
129
  }
130
- function Te(c, e) {
130
+ function ze(c, e) {
131
131
  const t = c.match(/^(\s+)(?:```)/);
132
132
  if (t === null)
133
133
  return e;
@@ -175,7 +175,7 @@ class q {
175
175
  fences(e) {
176
176
  const t = this.rules.block.fences.exec(e);
177
177
  if (t) {
178
- const n = t[0], s = Te(n, t[3] || "");
178
+ const n = t[0], s = ze(n, t[3] || "");
179
179
  return {
180
180
  type: "code",
181
181
  raw: n,
@@ -455,7 +455,7 @@ ${p}` : p;
455
455
  if ((n.length - r.length) % 2 === 0)
456
456
  return;
457
457
  } else {
458
- const r = $e(t[2], "()");
458
+ const r = Te(t[2], "()");
459
459
  if (r > -1) {
460
460
  const o = (t[0].indexOf("!") === 0 ? 5 : 4) + t[1].length + r;
461
461
  t[2] = t[2].substring(0, r), t[0] = t[0].substring(0, o).trim(), t[3] = "";
@@ -619,25 +619,25 @@ ${p}` : p;
619
619
  }
620
620
  }
621
621
  }
622
- const ze = /^(?:[ \t]*(?:\n|$))+/, Re = /^((?: {4}| {0,3}\t)[^\n]+(?:\n(?:[ \t]*(?:\n|$))*)?)+/, _e = /^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/, E = /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/, Se = /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/, le = /(?:[*+-]|\d{1,9}[.)])/, oe = f(/^(?!bull |blockCode|fences|blockquote|heading|html)((?:.|\n(?!\s*?\n|bull |blockCode|fences|blockquote|heading|html))+?)\n {0,3}(=+|-+) *(?:\n+|$)/).replace(/bull/g, le).replace(/blockCode/g, /(?: {4}| {0,3}\t)/).replace(/fences/g, / {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g, / {0,3}>/).replace(/heading/g, / {0,3}#{1,6}/).replace(/html/g, / {0,3}<[^\n>]+>\n/).getRegex(), D = /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/, Ie = /^[^\n]+/, O = /(?!\s*\])(?:\\.|[^\[\]\\])+/, Ae = f(/^ {0,3}\[(label)\]: *(?:\n[ \t]*)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n[ \t]*)?| *\n[ \t]*)(title))? *(?:\n+|$)/).replace("label", O).replace("title", /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/).getRegex(), Ee = f(/^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/).replace(/bull/g, le).getRegex(), P = "address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|search|section|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul", H = /<!--(?:-?>|[\s\S]*?(?:-->|$))/, Le = f("^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>\\n*|$)|<![A-Z][\\s\\S]*?(?:>\\n*|$)|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>\\n*|$)|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|</(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$))", "i").replace("comment", H).replace("tag", P).replace("attribute", / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(), ae = f(D).replace("hr", E).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("|lheading", "").replace("|table", "").replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", P).getRegex(), ve = f(/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/).replace("paragraph", ae).getRegex(), N = {
623
- blockquote: ve,
624
- code: Re,
625
- def: Ae,
626
- fences: _e,
627
- heading: Se,
622
+ const Re = /^(?:[ \t]*(?:\n|$))+/, _e = /^((?: {4}| {0,3}\t)[^\n]+(?:\n(?:[ \t]*(?:\n|$))*)?)+/, Se = /^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/, E = /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/, Ie = /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/, le = /(?:[*+-]|\d{1,9}[.)])/, oe = f(/^(?!bull |blockCode|fences|blockquote|heading|html)((?:.|\n(?!\s*?\n|bull |blockCode|fences|blockquote|heading|html))+?)\n {0,3}(=+|-+) *(?:\n+|$)/).replace(/bull/g, le).replace(/blockCode/g, /(?: {4}| {0,3}\t)/).replace(/fences/g, / {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g, / {0,3}>/).replace(/heading/g, / {0,3}#{1,6}/).replace(/html/g, / {0,3}<[^\n>]+>\n/).getRegex(), j = /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/, Ae = /^[^\n]+/, O = /(?!\s*\])(?:\\.|[^\[\]\\])+/, Ee = f(/^ {0,3}\[(label)\]: *(?:\n[ \t]*)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n[ \t]*)?| *\n[ \t]*)(title))? *(?:\n+|$)/).replace("label", O).replace("title", /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/).getRegex(), Le = f(/^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/).replace(/bull/g, le).getRegex(), P = "address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|search|section|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul", H = /<!--(?:-?>|[\s\S]*?(?:-->|$))/, ve = f("^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>\\n*|$)|<![A-Z][\\s\\S]*?(?:>\\n*|$)|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>\\n*|$)|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|</(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$))", "i").replace("comment", H).replace("tag", P).replace("attribute", / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(), ae = f(j).replace("hr", E).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("|lheading", "").replace("|table", "").replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", P).getRegex(), qe = f(/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/).replace("paragraph", ae).getRegex(), N = {
623
+ blockquote: qe,
624
+ code: _e,
625
+ def: Ee,
626
+ fences: Se,
627
+ heading: Ie,
628
628
  hr: E,
629
- html: Le,
629
+ html: ve,
630
630
  lheading: oe,
631
- list: Ee,
632
- newline: ze,
631
+ list: Le,
632
+ newline: Re,
633
633
  paragraph: ae,
634
634
  table: I,
635
- text: Ie
636
- }, ne = f("^ *([^\\n ].*)\\n {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)").replace("hr", E).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("blockquote", " {0,3}>").replace("code", "(?: {4}| {0,3} )[^\\n]").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", P).getRegex(), qe = {
635
+ text: Ae
636
+ }, ne = f("^ *([^\\n ].*)\\n {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)").replace("hr", E).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("blockquote", " {0,3}>").replace("code", "(?: {4}| {0,3} )[^\\n]").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", P).getRegex(), Be = {
637
637
  ...N,
638
638
  table: ne,
639
- paragraph: f(D).replace("hr", E).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("|lheading", "").replace("table", ne).replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", P).getRegex()
640
- }, Be = {
639
+ paragraph: f(j).replace("hr", E).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("|lheading", "").replace("table", ne).replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", P).getRegex()
640
+ }, Ce = {
641
641
  ...N,
642
642
  html: f(`^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)|<tag(?:"[^"]*"|'[^']*'|\\s[^'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))`).replace("comment", H).replace(/tag/g, "(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(),
643
643
  def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,
@@ -645,30 +645,30 @@ const ze = /^(?:[ \t]*(?:\n|$))+/, Re = /^((?: {4}| {0,3}\t)[^\n]+(?:\n(?:[ \t]*
645
645
  fences: I,
646
646
  // fences not supported
647
647
  lheading: /^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/,
648
- paragraph: f(D).replace("hr", E).replace("heading", ` *#{1,6} *[^
648
+ paragraph: f(j).replace("hr", E).replace("heading", ` *#{1,6} *[^
649
649
  ]`).replace("lheading", oe).replace("|table", "").replace("blockquote", " {0,3}>").replace("|fences", "").replace("|list", "").replace("|html", "").replace("|tag", "").getRegex()
650
- }, ce = /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/, Ce = /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/, he = /^( {2,}|\\)\n(?!\s*$)/, Pe = /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/, L = "\\p{P}\\p{S}", Ze = f(/^((?![*_])[\spunctuation])/, "u").replace(/punctuation/g, L).getRegex(), Me = /\[[^[\]]*?\]\([^\(\)]*?\)|`[^`]*?`|<[^<>]*?>/g, Qe = f(/^(?:\*+(?:((?!\*)[punct])|[^\s*]))|^_+(?:((?!_)[punct])|([^\s_]))/, "u").replace(/punct/g, L).getRegex(), je = f("^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\*)[punct](\\*+)(?=[\\s]|$)|[^punct\\s](\\*+)(?!\\*)(?=[punct\\s]|$)|(?!\\*)[punct\\s](\\*+)(?=[^punct\\s])|[\\s](\\*+)(?!\\*)(?=[punct])|(?!\\*)[punct](\\*+)(?!\\*)(?=[punct])|[^punct\\s](\\*+)(?=[^punct\\s])", "gu").replace(/punct/g, L).getRegex(), De = f("^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)|[^_]+(?=[^_])|(?!_)[punct](_+)(?=[\\s]|$)|[^punct\\s](_+)(?!_)(?=[punct\\s]|$)|(?!_)[punct\\s](_+)(?=[^punct\\s])|[\\s](_+)(?!_)(?=[punct])|(?!_)[punct](_+)(?!_)(?=[punct])", "gu").replace(/punct/g, L).getRegex(), Oe = f(/\\([punct])/, "gu").replace(/punct/g, L).getRegex(), He = f(/^<(scheme:[^\s\x00-\x1f<>]*|email)>/).replace("scheme", /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/).replace("email", /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/).getRegex(), Ne = f(H).replace("(?:-->|$)", "-->").getRegex(), Ue = f("^comment|^</[a-zA-Z][\\w:-]*\\s*>|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^<![a-zA-Z]+\\s[\\s\\S]*?>|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>").replace("comment", Ne).replace("attribute", /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/).getRegex(), B = /(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/, Fe = f(/^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/).replace("label", B).replace("href", /<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/).replace("title", /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/).getRegex(), pe = f(/^!?\[(label)\]\[(ref)\]/).replace("label", B).replace("ref", O).getRegex(), ue = f(/^!?\[(ref)\](?:\[\])?/).replace("ref", O).getRegex(), We = f("reflink|nolink(?!\\()", "g").replace("reflink", pe).replace("nolink", ue).getRegex(), U = {
650
+ }, ce = /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/, Pe = /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/, he = /^( {2,}|\\)\n(?!\s*$)/, Ze = /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/, L = "\\p{P}\\p{S}", Me = f(/^((?![*_])[\spunctuation])/, "u").replace(/punctuation/g, L).getRegex(), Qe = /\[[^[\]]*?\]\([^\(\)]*?\)|`[^`]*?`|<[^<>]*?>/g, De = f(/^(?:\*+(?:((?!\*)[punct])|[^\s*]))|^_+(?:((?!_)[punct])|([^\s_]))/, "u").replace(/punct/g, L).getRegex(), je = f("^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\*)[punct](\\*+)(?=[\\s]|$)|[^punct\\s](\\*+)(?!\\*)(?=[punct\\s]|$)|(?!\\*)[punct\\s](\\*+)(?=[^punct\\s])|[\\s](\\*+)(?!\\*)(?=[punct])|(?!\\*)[punct](\\*+)(?!\\*)(?=[punct])|[^punct\\s](\\*+)(?=[^punct\\s])", "gu").replace(/punct/g, L).getRegex(), Oe = f("^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)|[^_]+(?=[^_])|(?!_)[punct](_+)(?=[\\s]|$)|[^punct\\s](_+)(?!_)(?=[punct\\s]|$)|(?!_)[punct\\s](_+)(?=[^punct\\s])|[\\s](_+)(?!_)(?=[punct])|(?!_)[punct](_+)(?!_)(?=[punct])", "gu").replace(/punct/g, L).getRegex(), He = f(/\\([punct])/, "gu").replace(/punct/g, L).getRegex(), Ne = f(/^<(scheme:[^\s\x00-\x1f<>]*|email)>/).replace("scheme", /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/).replace("email", /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/).getRegex(), Ue = f(H).replace("(?:-->|$)", "-->").getRegex(), Fe = f("^comment|^</[a-zA-Z][\\w:-]*\\s*>|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^<![a-zA-Z]+\\s[\\s\\S]*?>|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>").replace("comment", Ue).replace("attribute", /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/).getRegex(), B = /(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/, We = f(/^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/).replace("label", B).replace("href", /<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/).replace("title", /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/).getRegex(), pe = f(/^!?\[(label)\]\[(ref)\]/).replace("label", B).replace("ref", O).getRegex(), ue = f(/^!?\[(ref)\](?:\[\])?/).replace("ref", O).getRegex(), Xe = f("reflink|nolink(?!\\()", "g").replace("reflink", pe).replace("nolink", ue).getRegex(), U = {
651
651
  _backpedal: I,
652
652
  // only used for GFM url
653
- anyPunctuation: Oe,
654
- autolink: He,
655
- blockSkip: Me,
653
+ anyPunctuation: He,
654
+ autolink: Ne,
655
+ blockSkip: Qe,
656
656
  br: he,
657
- code: Ce,
657
+ code: Pe,
658
658
  del: I,
659
- emStrongLDelim: Qe,
659
+ emStrongLDelim: De,
660
660
  emStrongRDelimAst: je,
661
- emStrongRDelimUnd: De,
661
+ emStrongRDelimUnd: Oe,
662
662
  escape: ce,
663
- link: Fe,
663
+ link: We,
664
664
  nolink: ue,
665
- punctuation: Ze,
665
+ punctuation: Me,
666
666
  reflink: pe,
667
- reflinkSearch: We,
668
- tag: Ue,
669
- text: Pe,
667
+ reflinkSearch: Xe,
668
+ tag: Fe,
669
+ text: Ze,
670
670
  url: I
671
- }, Xe = {
671
+ }, Ge = {
672
672
  ...U,
673
673
  link: f(/^!?\[(label)\]\((.*?)\)/).replace("label", B).getRegex(),
674
674
  reflink: f(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label", B).getRegex()
@@ -679,19 +679,19 @@ const ze = /^(?:[ \t]*(?:\n|$))+/, Re = /^((?: {4}| {0,3}\t)[^\n]+(?:\n(?:[ \t]*
679
679
  _backpedal: /(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/,
680
680
  del: /^(~~?)(?=[^\s~])([\s\S]*?[^\s~])\1(?=[^~]|$)/,
681
681
  text: /^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|https?:\/\/|ftp:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/
682
- }, Ge = {
682
+ }, Ve = {
683
683
  ...Q,
684
684
  br: f(he).replace("{2,}", "*").getRegex(),
685
685
  text: f(Q.text).replace("\\b_", "\\b_| {2,}\\n").replace(/\{2,\}/g, "*").getRegex()
686
686
  }, v = {
687
687
  normal: N,
688
- gfm: qe,
689
- pedantic: Be
688
+ gfm: Be,
689
+ pedantic: Ce
690
690
  }, S = {
691
691
  normal: U,
692
692
  gfm: Q,
693
- breaks: Ge,
694
- pedantic: Xe
693
+ breaks: Ve,
694
+ pedantic: Ge
695
695
  };
696
696
  class w {
697
697
  constructor(e) {
@@ -1283,9 +1283,9 @@ k(A, "passThroughHooks", /* @__PURE__ */ new Set([
1283
1283
  "postprocess",
1284
1284
  "processAllTokens"
1285
1285
  ]));
1286
- class Ve {
1286
+ class Je {
1287
1287
  constructor(...e) {
1288
- k(this, "defaults", j());
1288
+ k(this, "defaults", D());
1289
1289
  k(this, "options", this.setOptions);
1290
1290
  k(this, "parse", this.parseMarkdown(!0));
1291
1291
  k(this, "parseInline", this.parseMarkdown(!1));
@@ -1456,14 +1456,14 @@ Please report this to https://github.com/markedjs/marked.`, e) {
1456
1456
  };
1457
1457
  }
1458
1458
  }
1459
- const T = new Ve();
1459
+ const T = new Je();
1460
1460
  function u(c, e) {
1461
1461
  return T.parse(c, e);
1462
1462
  }
1463
1463
  u.options = u.setOptions = function(c) {
1464
1464
  return T.setOptions(c), u.defaults = T.defaults, se(u.defaults), u;
1465
1465
  };
1466
- u.getDefaults = j;
1466
+ u.getDefaults = D;
1467
1467
  u.defaults = z;
1468
1468
  u.use = function(...c) {
1469
1469
  return T.use(...c), u.defaults = T.defaults, se(u.defaults), u;
@@ -1488,30 +1488,30 @@ u.walkTokens;
1488
1488
  u.parseInline;
1489
1489
  y.parse;
1490
1490
  w.lex;
1491
- const Je = {
1492
- props: ["source"],
1491
+ const Ke = {
1492
+ mixins: [xe],
1493
1493
  data() {
1494
1494
  return {
1495
1495
  markedText: null
1496
1496
  };
1497
1497
  },
1498
- mounted() {
1498
+ async mounted() {
1499
1499
  try {
1500
- this.markedText = u(this.source);
1500
+ await this.getData(), this.markedText = u(this.sourceData);
1501
1501
  } catch (c) {
1502
1502
  console.error(c);
1503
1503
  }
1504
1504
  }
1505
- }, Ke = { class: "relative select-auto h-full py-4 rounded-xl p-4 box-border bg-white custom-scrollbar" }, Ye = ["innerHTML"];
1506
- function et(c, e, t, n, s, i) {
1507
- return V(), J("div", Ke, [
1505
+ }, Ye = { class: "relative select-auto h-full py-4 rounded-xl p-4 box-border bg-white custom-scrollbar" }, et = ["innerHTML"];
1506
+ function tt(c, e, t, n, s, i) {
1507
+ return V(), J("div", Ye, [
1508
1508
  s.markedText ? (V(), J("div", {
1509
1509
  key: 0,
1510
1510
  innerHTML: s.markedText
1511
- }, null, 8, Ye)) : de("", !0)
1511
+ }, null, 8, et)) : be("", !0)
1512
1512
  ]);
1513
1513
  }
1514
- const it = /* @__PURE__ */ xe(Je, [["render", et]]);
1514
+ const rt = /* @__PURE__ */ de(Ke, [["render", tt]]);
1515
1515
  export {
1516
- it as default
1516
+ rt as default
1517
1517
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opengis/bi",
3
- "version": "1.0.11",
3
+ "version": "1.0.12",
4
4
  "description": "BI data visualization module",
5
5
  "main": "dist/bi.js",
6
6
  "browser": "dist/bi.umd.cjs",
@@ -36,17 +36,19 @@
36
36
  "dependencies": {
37
37
  "@grpc/grpc-js": "^1.9.13",
38
38
  "@grpc/proto-loader": "^0.6.9",
39
- "carto": "^0.16.3",
40
39
  "@mapbox/sphericalmercator": "^1.2.0",
41
- "@opengis/fastify-table": "^1.1.14",
42
- "@opengis/v3-core": "^0.1.97",
40
+ "@opengis/fastify-table": "^1.1.15",
41
+ "@opengis/v3-core": "^0.1.103",
42
+ "@opengis/v3-filter": "^0.0.31",
43
43
  "axios": "^1.3.1",
44
+ "carto": "^0.16.3",
44
45
  "cross-env": "^7.0.3",
45
46
  "d3-format": "^3.1.0",
46
47
  "echarts": "^5.5.1",
47
48
  "fastify": "^4.26.1",
48
49
  "fastify-plugin": "^4.0.0",
49
50
  "js-yaml": "^4.1.0",
51
+ "maplibre-gl": "^4.7.1",
50
52
  "marked": "^14.1.2",
51
53
  "vite": "^5.1.5",
52
54
  "vue": "^3.4.27",
@@ -64,4 +66,4 @@
64
66
  "vitepress-plugin-tabs": "^0.5.0",
65
67
  "vitepress-sidebar": "^1.22.0"
66
68
  }
67
- }
69
+ }
@@ -45,12 +45,31 @@ export default async function data({
45
45
  return { message: 'not found ' + id, status: 404 };
46
46
  }
47
47
 
48
+ if (index?.filters?.filter((el) => el?.type === 'Check')?.length) {
49
+ await Promise.all(index.filters.filter((el) => el?.type === 'Check' && el?.data).map(async (el) => {
50
+ const options = await getTemplate('cls', el.data);
51
+ Object.assign(el, { options });
52
+ }));
53
+ }
54
+
48
55
 
49
56
  const data = index;
50
57
  data.type = 'file';
51
58
  const { table } = data?.data || { table: data?.table_name };
52
59
  // console.log(fileData)
53
- const widgets = fileData.filter(el => el[0] !== 'index.yml').map(el => el[1].data ? ({ name: el[0].split('.')[0], type: el[1].type, text: el[1].text, style: el[1].style, data: el[1].data }) : { name: el[0].split('.')[0], text: el[1] });
60
+ const widgets = fileData
61
+ .filter((el) => el[0] !== 'index.yml')
62
+ .map((el) =>
63
+ el[1].data
64
+ ? {
65
+ name: el[0].split('.')[0],
66
+ type: el[1].type,
67
+ title: el[1].title,
68
+ style: el[1].style,
69
+ data: el[1].data
70
+ }
71
+ : { name: el[0].split('.')[0], title: el[1] }
72
+ );
54
73
 
55
74
  const { fields = [] } = table ? await pg.query(`select * from ${table} limit 1`) : {};
56
75
 
@@ -12,8 +12,7 @@ export default async function data({
12
12
  pg = pgClients.client, funcs = {}, query = {},
13
13
  }) {
14
14
  const time = Date.now();
15
- const { config = {} } = funcs;
16
- const { dashboard, widget } = query;
15
+ const { dashboard, widget, filter, search, samples } = query;
17
16
 
18
17
  if (!widget && !dashboard) {
19
18
  return { message: 'not enough params: widget or dashboard required', status: 400 };
@@ -24,56 +23,61 @@ export default async function data({
24
23
  await pg.query(`select dashboard_id as id, table_name as "tableName" from bi.dashboard where $1 in (dashboard_id, name)`, [dashboard]).then((res1) => res1.rows?.[0] || {}) : {};
25
24
 
26
25
 
27
- if (!dashboardData && dashboard && !id) return 'dashboard not found';
28
-
29
- // return { t: 111, data: dashboardData, dashboard }
30
-
31
- const widgetData = dashboard ? dashboardData?.find(el => el[0]?.includes(widget))?.[1] : await getTemplate('widget', widget);
32
-
33
-
34
- if (dashboardData && !widgetData) {
35
- return widgetData
26
+ if (!dashboardData && dashboard && !id) {
27
+ return { message: `dashboard not found: ${dashboard}`, status: 404 };
36
28
  }
37
29
 
30
+ const widgetData = dashboard ? dashboardData?.find(el => el[0]?.includes(widget || 'index'))?.[1] : await getTemplate('widget', widget);
31
+
38
32
  if (!id && !dashboardData && !widgetData) {
39
- return { message: { root: config?.local ? dashboardDir : undefined, error: `not found`, widget, dashboard }, status: 404 };
33
+ return { message: { error: `not found`, widget, dashboard }, status: 404 };
40
34
  }
41
35
 
42
36
  const q = `select *, coalesce(data::jsonb, '{}'::jsonb) || jsonb_build_object('table', table_name) as data from bi.widget where dashboard_id=$1 and name=$2`;
43
- const { type, text, data, controls, style, options } = widgetData || await pg.query(q, [id || dashboard, widget]).then((res1) => res1.rows?.[0] || {});
37
+ const { type, text, data = {}, controls, style, options } = widgetData || await pg.query(q, [id || dashboard, widget]).then((res1) => res1.rows?.[0] || {});
44
38
 
45
39
  if (typeof widgetData === 'string') {
46
40
  return { title: false, source: widgetData };
47
41
  }
48
42
 
49
- if (!data?.table && tableName) {
50
- Object.assign(data, { table: tableName });
43
+ if (!data?.table && tableName || widgetData?.table_name) {
44
+ Object.assign(data, { table: tableName || widgetData?.table_name });
51
45
  }
52
46
 
53
47
  if (!data?.table) {
54
48
  return { error: /* json.error || */ `invalid ${widget ? 'widget' : 'dashboard'}: 1`, status: 500 };
55
49
  }
56
50
 
51
+ // types
52
+ const { fields: cols } = await pg.queryCache(`select * from ${data.table} limit 0`);
53
+ const columnTypes = cols.map(el => ({ name: el.name, type: pg.pgType[el.dataTypeID] }))
54
+
57
55
  // data param
58
- const { x, metric, table, where, groupby, xName } = normalizeData(data, query);
56
+ const { x, metric, table, where, groupby, xName } = normalizeData(data, query, columnTypes);
59
57
 
60
58
  // auto Index
61
59
  if (pg.pk[data.table]) {
62
60
  autoIndex({ table: data.table, columns: [data?.time].concat([xName]).concat([groupby]).filter(el => el) }).catch(err => console.log(err))
63
61
  }
64
62
 
63
+
65
64
  // get group
66
65
  const groupData = groupby ? await pg.query(`select ${groupby} as name ,count(*) from ${table} group by ${groupby} order by count(*) desc limit 20`).then(el => el.rows) : null;
67
66
 
68
67
  if (query.sql === '2') return { x, metric, table, data, groupData };
69
68
 
70
- const sql = (chartSQL[type] || chartSQL['chart'])({ where, metric, table, x, groupData, groupby });
69
+ const order = data.order || (type === 'listbar' ? 'metric desc' : null);
70
+
71
+ const { optimizedSQL = `select * from ${table}` } = filter || search ? await funcs.getFilterSQL({
72
+ pg, table, filter, search,
73
+ }) : {};
71
74
 
75
+ const sql = (chartSQL[type] || chartSQL['chart'])({ where, metric, table: `(${optimizedSQL})q`, x, groupData, groupby, order, samples });
72
76
 
73
77
  if (query.sql) return sql;
74
78
 
75
79
  if (!sql || sql?.includes('undefined')) {
76
- return { message: { error: 'invalid sql', type, sql, where, metric, table, x, groupData, groupby }, status: 500 };
80
+ return { message: { error: 'invalid sql', type, sql, where, metric, table: `(${optimizedSQL})q`, x, groupData, groupby }, status: 500 };
77
81
  }
78
82
 
79
83
  const { rows, fields } = await pg.query(sql); // test with limit
@@ -87,12 +91,20 @@ export default async function data({
87
91
  dimensionsType: fields.map(el => pg.pgType[el.dataTypeID]),
88
92
  type,
89
93
 
90
- text: text ? text : data.text,
94
+ text: text ? text : (widgetData?.title || data.text),
91
95
  //data: query.format === 'data' ? dimensions.map(el => rows.map(r => r[el])) : undefined,
92
96
  source: query.format === 'array' ? dimensions.map(el => rows.map(r => r[el])) : rows,
93
97
  style,
94
98
  options,
95
99
  controls,
100
+ params: {
101
+ x,
102
+ metric,
103
+ table,
104
+ groupby,
105
+ sql: funcs?.config.local ? optimizedSQL : undefined,
106
+ },
107
+ columnTypes,
96
108
  };
97
109
  return res;
98
110
 
@@ -1,19 +1,20 @@
1
- function number({ metric, where, table }) {
2
- const sql = `select ${metric} from ${table} where ${where}`
1
+ function number({ metric, where, table, samples }) {
2
+ const sql = `select ${metric} from ${table} where ${where} ${samples ? 'limit 10' : ''}`
3
3
  return sql;
4
4
  }
5
- function table({ columns, table, where }) {
6
- return `select ${columns.map(el => el.name || el)}::text from ${table} where ${where} limit 20 `
5
+ function table({ columns, table, where, samples }) {
6
+ return `select ${columns.map(el => el.name || el)}::text from ${table} where ${where} ${samples ? 'limit 10' : 'limit 20'} `
7
7
  }
8
8
 
9
- function chart({ metric, where, table, x, groupby, groupData }) {
9
+ function chart({ metric, where, table, x, groupby, groupData, order, samples }) {
10
10
 
11
- const metricData = groupData?.map(el => `${metric} filter (where ${groupby}='${el.name}') as "${el.name}"`).join(',') || metric
11
+ const metricData = groupData?.map(el => `${metric} filter (where ${groupby}='${el.name}') as "${el.name}"`).join(',') || `${metric} as metric`
12
12
  const sql = `select ${x}, ${metricData}
13
13
  from ${table}
14
14
  where ${where}
15
15
  group by ${x}
16
- order by ${x}`;
16
+ order by ${order || x}
17
+ ${samples ? 'limit 10' : ''}`;
17
18
  return sql;
18
19
  }
19
20
 
@@ -1,15 +1,21 @@
1
- function normalizeData(data, query = {}) {
1
+ function normalizeData(data, query = {}, columnTypes = []) {
2
+ ['x', 'groupby', 'granularity'].forEach(el => {
3
+ //console.log(el, query[el], columnTypes.find(col => col.name == query[el]))
4
+ if (!columnTypes.find(col => col.name == query[el])) { delete query[el]; }
5
+ })
2
6
 
7
+ if (!columnTypes.find(col => col.type === 'numeric' && col.name == query.metric)) { delete query.metric; }
3
8
 
4
- const granularity = query.granularity || data.granularity;
9
+ const xName = query.x || (Array.isArray(data.x) ? data.x[0] : data.x);
10
+ const xTYpe = columnTypes.find(el => el.name == xName)?.type;
5
11
 
12
+ const granularity = xTYpe === 'date' ? (query.granularity || data.granularity || 'year') : null;
6
13
 
7
- const xName = Array.isArray(data.x) ? data.x[0] : data.x || query.x;
8
14
 
9
15
  const x = (granularity ? `date_trunc('${granularity}',${xName})::date` : null) || xName;
10
16
 
11
17
  const metrics = Array.isArray(data.metrics) ? data.metrics : [data.metrics];
12
- const metric = metrics.length ? metrics?.filter(el => el).map(el => `${el.operator || 'sum'}(${el.name || el})`) : 'count(*)';
18
+ const metric = (query.metric ? `sum(${query.metric})` : null) || (metrics.length ? metrics?.filter(el => el).map(el => `${el.operator || 'sum'}(${el.name || el})`) : 'count(*)');
13
19
 
14
20
  const table = data.table;
15
21
  const where = data.query || 'true';
@@ -1,7 +1,11 @@
1
1
  export default async function widgetAdd({ pg, funcs, params = {}, body }) {
2
2
  try {
3
3
  const time = Date.now();
4
- console.log(body);
4
+ const tableName = body.table_name;
5
+ const checkTable = await pg.query(`select * from bi.dashboard where $1 in (table_name)`, [
6
+ tableName
7
+ ]);
8
+ if (!checkTable.rows.length) return { message: 'bad params', status: 401 };
5
9
  const res = await funcs.dataInsert({
6
10
  table: 'bi.dashboard',
7
11
  data: body
@@ -8,7 +8,11 @@ export default async function dashboardEdit({
8
8
  status: 400,
9
9
  }
10
10
  }
11
-
11
+ const tableName = body.table_name;
12
+ const checkTable = await pg.query(`select * from bi.dashboard where $1 in (table_name)`, [
13
+ tableName
14
+ ]);
15
+ if (!checkTable.rows.length) return { message: 'bad params', status: 401 };
12
16
  const { name: dashboardName } = params;
13
17
  const row = await pg.query(`select dashboard_id from bi.dashboard where $1 in (dashboard_id, name)`, [dashboardName]).then((res1) => res1.rows?.[0] || {});
14
18
  const { dashboard_id: dashboardId } = row;
@@ -1,15 +1,26 @@
1
- export default async function widgetAdd({
2
- pg, funcs, params = {}, body = {},
3
- }) {
1
+ export default async function widgetAdd({ pg, funcs, params = {}, body = {} }) {
4
2
  const { name: dashboardName } = params;
5
3
  if (!dashboardName) {
6
4
  return { message: 'not enough params: id', status: 400 };
7
5
  }
8
-
6
+ const tableName = body.table_name;
9
7
  try {
10
- const row = await pg.query(`select dashboard_id, widgets, panels from bi.dashboard where $1 in (dashboard_id,name)`, [dashboardName]).then((res) => res.rows?.[0] || {});
8
+ const row = await pg
9
+ .query(
10
+ `select dashboard_id, widgets, panels from bi.dashboard where $1 in (dashboard_id,name)`,
11
+ [dashboardName]
12
+ )
13
+ .then((res) => res.rows?.[0] || {});
14
+
15
+ const checkTable = await pg.query(`select * from bi.widget where $1 in (table_name)`, [
16
+ tableName
17
+ ]);
18
+ if (!checkTable.rows.length) return { message: 'bad params', status: 401 };
19
+
11
20
  const { dashboard_id: dashboardId } = row;
12
21
 
22
+ const generatedName = generateUniqueName(body.type);
23
+ body.name = generatedName;
13
24
  const res = await funcs.dataUpdate({
14
25
  table: 'bi.dashboard',
15
26
  id: dashboardId,
@@ -20,14 +31,19 @@ export default async function widgetAdd({
20
31
  });
21
32
  const res2 = await funcs.dataInsert({
22
33
  table: 'bi.widget',
23
- data: { ...body, data: body, dashboard_id: dashboardId },
34
+ data: { ...body, data: body, dashboard_id: dashboardId }
24
35
  });
25
36
  return {
26
37
  message: `Added widget to ${dashboardName}`,
27
38
  status: 200,
28
- rows: res,
39
+ rows: res
29
40
  };
30
41
  } catch (err) {
31
42
  return { error: err.toString(), status: 500 };
32
43
  }
33
44
  }
45
+ function generateUniqueName(prefix = 'bar') {
46
+ const randomPart = Math.floor(Math.random() * 10000);
47
+ const timestamp = Date.now();
48
+ return `${prefix}_${randomPart}_${timestamp}`;
49
+ }