precision-dashwidgets 0.5.0 → 0.5.2
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.
- package/dist/basedecoder-PoXbLGBV-BL0bCGZI.mjs +88 -0
- package/dist/core-l0sNRNKZ.mjs +1 -0
- package/dist/deflate-BQVLA3Ul.mjs +10 -0
- package/dist/deflate-DbhbvOaP-D8NSBt31.mjs +10 -0
- package/dist/{duckdb-browser-CI2dpY-v-CoCsU0kJ.mjs → duckdb-browser-CI2dpY-v-D1qQUOov.mjs} +14 -19
- package/dist/index-BHHg5z03.mjs +47215 -0
- package/dist/index-CRAkqt4--8ZLRoGIu.mjs +4 -0
- package/dist/index-GF8k2nCC-DnpFPSAr.mjs +4 -0
- package/dist/index-Hx8PFhs9.mjs +27802 -0
- package/dist/index-Oh_goZGT-H9AAGZr8.mjs +9 -0
- package/dist/index-UOUUzHJY-DJVMXBUa.mjs +61 -0
- package/dist/index-dhOjlnSX-Biz-kopS.mjs +278 -0
- package/dist/index-u1qleOVs-ZJVnnKAV.mjs +8 -0
- package/dist/jpeg-CqPRbuRp-D8jmb2jk.mjs +514 -0
- package/dist/jpeg-l5M1J8Gh.mjs +514 -0
- package/dist/lerc-BipMr5R9.mjs +1034 -0
- package/dist/lerc-XufrP0FH-SNCeY3ab.mjs +1029 -0
- package/dist/lzw-DQ6ibF74-B90aSslP.mjs +84 -0
- package/dist/lzw-u9cBMr9g.mjs +84 -0
- package/dist/packbits-BuzK6gM3-6Um4hupZ.mjs +24 -0
- package/dist/packbits-dQba4PyI.mjs +24 -0
- package/dist/pako.esm-Bx5X36Wo-CzWah3nf.mjs +1053 -0
- package/dist/pako.esm-D_m2s4NW.mjs +1053 -0
- package/dist/precision-dashwidgets.es.js +7 -23222
- package/dist/precision-dashwidgets.umd.js +4801 -63
- package/dist/raw-CaSL8pVO-AR0tnXz4.mjs +9 -0
- package/dist/raw-KFPBw5cQ.mjs +9 -0
- package/dist/style.css +1 -1
- package/dist/webimage--SJddlky-F_hESl4q.mjs +19 -0
- package/dist/webimage-CBOAIeUr.mjs +19 -0
- package/package.json +6 -5
- package/dist/useGetToken-DaxIvkvl-BZdrKpSJ.mjs +0 -18
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { defineComponent as y, ref as t, openBlock as u, createElementBlock as c, createElementVNode as l, withDirectives as p, vModelText as r, withKeys as b, createCommentVNode as k } from "vue";
|
|
2
|
+
import { k as U } from "./index-Hx8PFhs9.mjs";
|
|
3
|
+
const g = { class: "ai-plot-widget" }, h = { class: "ai-plot-field" }, x = {
|
|
4
|
+
key: 0,
|
|
5
|
+
class: "ai-plot-field"
|
|
6
|
+
}, C = /* @__PURE__ */ y({
|
|
7
|
+
__name: "AiPlotly",
|
|
8
|
+
props: {
|
|
9
|
+
srcUrl: {}
|
|
10
|
+
},
|
|
11
|
+
setup(s) {
|
|
12
|
+
const a = t(s.srcUrl || ""), o = t(""), n = t(!1), d = t(null);
|
|
13
|
+
async function v() {
|
|
14
|
+
a.value && (n.value = !0);
|
|
15
|
+
}
|
|
16
|
+
async function f() {
|
|
17
|
+
!o.value || n.value;
|
|
18
|
+
}
|
|
19
|
+
function m() {
|
|
20
|
+
}
|
|
21
|
+
return (D, e) => (u(), c("div", g, [
|
|
22
|
+
l("div", h, [
|
|
23
|
+
e[2] || (e[2] = l("label", null, "Data URL", -1)),
|
|
24
|
+
p(l("input", {
|
|
25
|
+
"onUpdate:modelValue": e[0] || (e[0] = (i) => a.value = i),
|
|
26
|
+
type: "text",
|
|
27
|
+
class: "ai-plot-input",
|
|
28
|
+
placeholder: "S3 Parquet URL",
|
|
29
|
+
onBlur: v
|
|
30
|
+
}, null, 544), [
|
|
31
|
+
[r, a.value]
|
|
32
|
+
])
|
|
33
|
+
]),
|
|
34
|
+
n.value ? (u(), c("div", x, [
|
|
35
|
+
e[3] || (e[3] = l("label", null, "Plot Description", -1)),
|
|
36
|
+
p(l("input", {
|
|
37
|
+
"onUpdate:modelValue": e[1] || (e[1] = (i) => o.value = i),
|
|
38
|
+
type: "text",
|
|
39
|
+
class: "ai-plot-input",
|
|
40
|
+
maxlength: 280,
|
|
41
|
+
placeholder: "Describe your plot...",
|
|
42
|
+
onKeyup: b(f, ["enter"])
|
|
43
|
+
}, null, 544), [
|
|
44
|
+
[r, o.value]
|
|
45
|
+
])
|
|
46
|
+
])) : k("", !0),
|
|
47
|
+
l("div", {
|
|
48
|
+
ref_key: "plotlyDiv",
|
|
49
|
+
ref: d,
|
|
50
|
+
class: "plot-container"
|
|
51
|
+
}, null, 512),
|
|
52
|
+
l("button", {
|
|
53
|
+
class: "ai-plot-btn",
|
|
54
|
+
onClick: m
|
|
55
|
+
}, "Save Widget Config")
|
|
56
|
+
]));
|
|
57
|
+
}
|
|
58
|
+
}), B = /* @__PURE__ */ U(C, [["__scopeId", "data-v-a1b59c7a"]]);
|
|
59
|
+
export {
|
|
60
|
+
B as AiPlotly
|
|
61
|
+
};
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
import { defineComponent as le, inject as te, ref as g, computed as F, watch as ne, onMounted as oe, onBeforeUnmount as re, openBlock as w, createElementBlock as E, createElementVNode as r, withDirectives as D, vModelText as ie, Fragment as M, renderList as N, toDisplayString as $, vModelSelect as W, createCommentVNode as ue } from "vue";
|
|
2
|
+
import { k as se, b as z } from "./index-Hx8PFhs9.mjs";
|
|
3
|
+
const ce = { class: "pp-container" }, pe = { class: "pp-header" }, ve = { class: "pp-controls" }, de = { class: "pp-field" }, me = ["disabled"], fe = { class: "pp-field" }, ye = ["disabled"], Se = ["value"], ge = ["value"], we = ["disabled"], Ee = ["value"], $e = { class: "pp-field" }, he = ["disabled"], Ae = {
|
|
4
|
+
key: 0,
|
|
5
|
+
class: "pp-message"
|
|
6
|
+
}, I = 100, _ = 12, B = "(other)", Ce = /* @__PURE__ */ le({
|
|
7
|
+
__name: "ProportionPlot",
|
|
8
|
+
props: {
|
|
9
|
+
apiUrl: {},
|
|
10
|
+
pkg: {},
|
|
11
|
+
srcUrl: {},
|
|
12
|
+
srcFileType: {},
|
|
13
|
+
srcFileId: {},
|
|
14
|
+
tableNameOverride: {}
|
|
15
|
+
},
|
|
16
|
+
setup(H) {
|
|
17
|
+
const y = H;
|
|
18
|
+
let O;
|
|
19
|
+
const V = te("duckdb");
|
|
20
|
+
if (!V)
|
|
21
|
+
throw new Error(
|
|
22
|
+
'[@pennsieve-viz/core] DuckDB store not provided. Please provide a DuckDB store via app.provide("duckdb", store)'
|
|
23
|
+
);
|
|
24
|
+
const C = V, c = g(null), b = g(null), v = g(
|
|
25
|
+
y.srcUrl || "https://temp-precision-dashboard-data.s3.us-east-1.amazonaws.com/precision_human_drg_data.parquet"
|
|
26
|
+
), j = F(() => C.formatIdFromUrl(v.value)), f = g(!1), d = g(""), S = g([]), p = g(""), m = g(""), R = `proportion-plot-${Math.random().toString(36).slice(2)}`;
|
|
27
|
+
ne(
|
|
28
|
+
() => ({ srcUrl: y.srcUrl, srcFileType: y.srcFileType, srcFileId: y.srcFileId, pkg: y.pkg, apiUrl: y.apiUrl }),
|
|
29
|
+
async ({ srcUrl: l, srcFileType: a, srcFileId: e, pkg: i, apiUrl: n }) => {
|
|
30
|
+
var o, s;
|
|
31
|
+
try {
|
|
32
|
+
if (l && (v.value = l), await L(), v.value) {
|
|
33
|
+
const A = a ?? (v.value.toLowerCase().endsWith(".csv") ? "csv" : "parquet");
|
|
34
|
+
await G(A, j.value);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const t = (o = i == null ? void 0 : i.content) == null ? void 0 : o.id, h = (s = i == null ? void 0 : i.content) == null ? void 0 : s.packageType;
|
|
38
|
+
if (t && n) {
|
|
39
|
+
const A = await Q(t, n);
|
|
40
|
+
if (!A) return;
|
|
41
|
+
const U = await K(t, A, n), x = h === "CSV" ? "csv" : "parquet", u = A.replace(/[^a-zA-Z0-9_.-]/g, "_");
|
|
42
|
+
v.value = U, await G(x, u);
|
|
43
|
+
}
|
|
44
|
+
} catch (t) {
|
|
45
|
+
console.error("[ProportionPlot] Load failed:", (t == null ? void 0 : t.message) || t), d.value = `Load failed: ${(t == null ? void 0 : t.message) || t}`;
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
{ immediate: !0 }
|
|
49
|
+
);
|
|
50
|
+
const T = /* @__PURE__ */ new Set(["VARCHAR", "STRING", "TEXT", "BOOL", "BOOLEAN", "DATE", "TIMESTAMP"]), Y = F(() => S.value.filter((l) => T.has(l.type) || l.type.startsWith("VARCHAR"))), q = F(() => S.value.filter((l) => !T.has(l.type)));
|
|
51
|
+
async function L() {
|
|
52
|
+
if (c.value) return;
|
|
53
|
+
const { connectionId: l } = await C.createConnection(`prop_${Date.now()}`);
|
|
54
|
+
c.value = l;
|
|
55
|
+
}
|
|
56
|
+
function Z(l) {
|
|
57
|
+
const a = String(l).replace(/[^A-Za-z0-9_]/g, "_");
|
|
58
|
+
return (/^[A-Za-z_]/.test(a) ? a : `t_${a}`).slice(0, 63);
|
|
59
|
+
}
|
|
60
|
+
async function G(l, a) {
|
|
61
|
+
c.value || await L();
|
|
62
|
+
const e = (a || y.srcFileId || v.value || "file").replace(/[^A-Za-z0-9]/g, "_");
|
|
63
|
+
f.value = !0, d.value = "Loading file into DuckDB…";
|
|
64
|
+
try {
|
|
65
|
+
const i = l ?? (v.value.toLowerCase().endsWith(".csv") ? "csv" : "parquet"), n = y.tableNameOverride || Z(`file_${e.slice(0, 48)}`), o = await C.loadFile(
|
|
66
|
+
v.value,
|
|
67
|
+
i,
|
|
68
|
+
n,
|
|
69
|
+
{},
|
|
70
|
+
c.value,
|
|
71
|
+
e
|
|
72
|
+
);
|
|
73
|
+
b.value = o, await X(!0);
|
|
74
|
+
} finally {
|
|
75
|
+
f.value = !1;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
function k(l) {
|
|
79
|
+
return '"' + String(l).replace(/"/g, '""') + '"';
|
|
80
|
+
}
|
|
81
|
+
async function X(l = !1) {
|
|
82
|
+
var a, e, i, n;
|
|
83
|
+
if (!b.value || !c.value) return;
|
|
84
|
+
const o = `PRAGMA table_info(${k(b.value)})`, s = await C.executeQuery(o, c.value);
|
|
85
|
+
if (S.value = s.map((t) => ({ name: String(t.name), type: String(t.type).toUpperCase() })), l || !p.value || !m.value) {
|
|
86
|
+
const t = S.value.filter((h) => T.has(h.type) || h.type.startsWith("VARCHAR"));
|
|
87
|
+
p.value = ((a = t[0]) == null ? void 0 : a.name) || ((e = S.value[0]) == null ? void 0 : e.name) || "", m.value = ((i = t[1]) == null ? void 0 : i.name) || ((n = t[0]) == null ? void 0 : n.name) || "";
|
|
88
|
+
}
|
|
89
|
+
d.value = `Columns: ${S.value.length}.`;
|
|
90
|
+
}
|
|
91
|
+
async function J() {
|
|
92
|
+
if (!(!b.value || !c.value)) {
|
|
93
|
+
if (!p.value || !m.value) {
|
|
94
|
+
d.value = "Pick both X and Y";
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
f.value = !0, d.value = "Computing proportions…";
|
|
98
|
+
try {
|
|
99
|
+
const l = k(b.value), a = k(p.value), e = k(m.value), i = `
|
|
100
|
+
WITH xf AS (
|
|
101
|
+
SELECT ${a} AS x, COUNT(*) AS c
|
|
102
|
+
FROM ${l}
|
|
103
|
+
GROUP BY 1
|
|
104
|
+
ORDER BY c DESC
|
|
105
|
+
LIMIT ${I}
|
|
106
|
+
),
|
|
107
|
+
yf AS (
|
|
108
|
+
SELECT ${e} AS y, COUNT(*) AS c
|
|
109
|
+
FROM ${l}
|
|
110
|
+
GROUP BY 1
|
|
111
|
+
ORDER BY c DESC
|
|
112
|
+
LIMIT ${_}
|
|
113
|
+
),
|
|
114
|
+
filtered AS (
|
|
115
|
+
SELECT src.*
|
|
116
|
+
FROM ${l} AS src
|
|
117
|
+
JOIN xf ON src.${a} = xf.x
|
|
118
|
+
),
|
|
119
|
+
labeled AS (
|
|
120
|
+
SELECT
|
|
121
|
+
${a} AS x,
|
|
122
|
+
CASE
|
|
123
|
+
WHEN ${e} IN (SELECT y FROM yf) THEN COALESCE(${e}, '(missing)')
|
|
124
|
+
ELSE '${B}'
|
|
125
|
+
END AS y
|
|
126
|
+
FROM filtered
|
|
127
|
+
),
|
|
128
|
+
counts AS (
|
|
129
|
+
SELECT x, y, COUNT(*)::DOUBLE AS n
|
|
130
|
+
FROM labeled
|
|
131
|
+
GROUP BY 1, 2
|
|
132
|
+
),
|
|
133
|
+
denom AS (
|
|
134
|
+
SELECT x, SUM(n) AS total
|
|
135
|
+
FROM counts
|
|
136
|
+
GROUP BY 1
|
|
137
|
+
),
|
|
138
|
+
props AS (
|
|
139
|
+
SELECT c.x, c.y, c.n / NULLIF(d.total, 0) AS p
|
|
140
|
+
FROM counts c
|
|
141
|
+
JOIN denom d USING (x)
|
|
142
|
+
)
|
|
143
|
+
SELECT * FROM props ORDER BY x, y;
|
|
144
|
+
`, n = await C.executeQuery(i, c.value);
|
|
145
|
+
if (!n.length) {
|
|
146
|
+
d.value = "No rows returned. Try different columns.", O.purge(R);
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
const o = Array.from(new Set(n.map((u) => String(u.x)))), s = Array.from(new Set(n.map((u) => String(u.y)))), t = (u, P) => `${u}\0${P}`, h = /* @__PURE__ */ new Map();
|
|
150
|
+
for (const u of n) h.set(t(String(u.x), String(u.y)), Number(u.p ?? 0));
|
|
151
|
+
const A = s.map((u) => ({
|
|
152
|
+
type: "bar",
|
|
153
|
+
name: u,
|
|
154
|
+
x: o,
|
|
155
|
+
y: o.map((P) => h.get(t(P, u)) ?? 0),
|
|
156
|
+
hovertemplate: `${m.value}=%{fullData.name}<br>${p.value}=%{x}<br>Proportion=%{y:.1%}<extra></extra>`
|
|
157
|
+
})), U = {
|
|
158
|
+
title: `${m.value} proportions within ${p.value}`,
|
|
159
|
+
barmode: "stack",
|
|
160
|
+
yaxis: { range: [0, 1], tickformat: ".0%", title: "Proportion" },
|
|
161
|
+
xaxis: { title: p.value },
|
|
162
|
+
legend: { orientation: "h", y: -0.2 },
|
|
163
|
+
margin: { t: 48, r: 16, b: 96, l: 56 }
|
|
164
|
+
};
|
|
165
|
+
await O.newPlot(R, A, U, { responsive: !0 });
|
|
166
|
+
const x = (o.length >= I ? ` Limited to top ${I} ${p.value}.` : "") + (s.length >= _ || s.includes(B) ? ` Limited to top ${_} ${m.value} (+ ${B}).` : "");
|
|
167
|
+
d.value = `Plotted ${s.length} categories across ${o.length} groups.${x}`;
|
|
168
|
+
} catch (l) {
|
|
169
|
+
console.error(l), d.value = `Error: ${(l == null ? void 0 : l.message) || l}`;
|
|
170
|
+
} finally {
|
|
171
|
+
f.value = !1;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
async function Q(l, a) {
|
|
176
|
+
var e, i;
|
|
177
|
+
const n = await z(), o = `${a}/packages/${l}/view?api_key=${n}`, s = await fetch(o);
|
|
178
|
+
if (!s.ok) return null;
|
|
179
|
+
const t = await s.json();
|
|
180
|
+
return (i = (e = t == null ? void 0 : t[0]) == null ? void 0 : e.content) == null ? void 0 : i.id;
|
|
181
|
+
}
|
|
182
|
+
async function K(l, a, e) {
|
|
183
|
+
const i = await z(), n = `${e}/packages/${l}/files/${a}?api_key=${i}`, o = await fetch(n);
|
|
184
|
+
if (!o.ok) throw new Error(`file url failed: ${o.status}`);
|
|
185
|
+
return (await o.json()).url;
|
|
186
|
+
}
|
|
187
|
+
function ee() {
|
|
188
|
+
return typeof window < "u" && typeof document < "u";
|
|
189
|
+
}
|
|
190
|
+
async function ae() {
|
|
191
|
+
return ee() ? O || (await new Promise((l, a) => {
|
|
192
|
+
const e = document.createElement("script");
|
|
193
|
+
e.src = "https://cdn.plot.ly/plotly-2.35.3.min.js", e.onload = () => l(), e.onerror = () => a(new Error("Failed to load Plotly CDN")), document.head.appendChild(e);
|
|
194
|
+
}), O = window.Plotly, O) : null;
|
|
195
|
+
}
|
|
196
|
+
return oe(async () => {
|
|
197
|
+
await L(), await ae();
|
|
198
|
+
}), re(async () => {
|
|
199
|
+
c.value && await C.closeConnection(c.value);
|
|
200
|
+
}), (l, a) => (w(), E("div", ce, [
|
|
201
|
+
r("div", pe, [
|
|
202
|
+
r("div", ve, [
|
|
203
|
+
r("div", de, [
|
|
204
|
+
a[3] || (a[3] = r("label", null, "Data URL", -1)),
|
|
205
|
+
D(r("input", {
|
|
206
|
+
"onUpdate:modelValue": a[0] || (a[0] = (e) => v.value = e),
|
|
207
|
+
type: "text",
|
|
208
|
+
class: "pp-input pp-input--url",
|
|
209
|
+
disabled: f.value,
|
|
210
|
+
placeholder: "https://.../file.parquet"
|
|
211
|
+
}, null, 8, me), [
|
|
212
|
+
[ie, v.value]
|
|
213
|
+
])
|
|
214
|
+
]),
|
|
215
|
+
r("div", fe, [
|
|
216
|
+
r("div", null, [
|
|
217
|
+
a[5] || (a[5] = r("label", null, "X (group) column", -1)),
|
|
218
|
+
D(r("select", {
|
|
219
|
+
"onUpdate:modelValue": a[1] || (a[1] = (e) => p.value = e),
|
|
220
|
+
class: "pp-select",
|
|
221
|
+
disabled: f.value || S.value.length === 0
|
|
222
|
+
}, [
|
|
223
|
+
a[4] || (a[4] = r("option", {
|
|
224
|
+
disabled: "",
|
|
225
|
+
value: ""
|
|
226
|
+
}, "— choose —", -1)),
|
|
227
|
+
(w(!0), E(M, null, N(Y.value, (e) => (w(), E("option", {
|
|
228
|
+
key: e.name,
|
|
229
|
+
value: e.name
|
|
230
|
+
}, $(e.name) + " (" + $(e.type) + ")", 9, Se))), 128)),
|
|
231
|
+
(w(!0), E(M, null, N(q.value, (e) => (w(), E("option", {
|
|
232
|
+
key: e.name + "-num",
|
|
233
|
+
value: e.name
|
|
234
|
+
}, $(e.name) + " (" + $(e.type) + ")", 9, ge))), 128))
|
|
235
|
+
], 8, ye), [
|
|
236
|
+
[W, p.value]
|
|
237
|
+
])
|
|
238
|
+
]),
|
|
239
|
+
r("div", null, [
|
|
240
|
+
a[7] || (a[7] = r("label", null, "Y (category) column", -1)),
|
|
241
|
+
D(r("select", {
|
|
242
|
+
"onUpdate:modelValue": a[2] || (a[2] = (e) => m.value = e),
|
|
243
|
+
class: "pp-select",
|
|
244
|
+
disabled: f.value || S.value.length === 0
|
|
245
|
+
}, [
|
|
246
|
+
a[6] || (a[6] = r("option", {
|
|
247
|
+
disabled: "",
|
|
248
|
+
value: ""
|
|
249
|
+
}, "— choose —", -1)),
|
|
250
|
+
(w(!0), E(M, null, N(Y.value, (e) => (w(), E("option", {
|
|
251
|
+
key: e.name + "-y",
|
|
252
|
+
value: e.name
|
|
253
|
+
}, $(e.name) + " (" + $(e.type) + ")", 9, Ee))), 128))
|
|
254
|
+
], 8, we), [
|
|
255
|
+
[W, m.value]
|
|
256
|
+
])
|
|
257
|
+
])
|
|
258
|
+
]),
|
|
259
|
+
r("div", $e, [
|
|
260
|
+
r("button", {
|
|
261
|
+
class: "pp-btn pp-btn--primary",
|
|
262
|
+
disabled: !p.value || !m.value || f.value || !c.value || !b.value,
|
|
263
|
+
onClick: J
|
|
264
|
+
}, $(f.value ? "Working…" : "Plot"), 9, he),
|
|
265
|
+
d.value ? (w(), E("div", Ae, $(d.value), 1)) : ue("", !0)
|
|
266
|
+
])
|
|
267
|
+
])
|
|
268
|
+
]),
|
|
269
|
+
r("div", {
|
|
270
|
+
id: R,
|
|
271
|
+
class: "pp-plot"
|
|
272
|
+
})
|
|
273
|
+
]));
|
|
274
|
+
}
|
|
275
|
+
}), ke = /* @__PURE__ */ se(Ce, [["__scopeId", "data-v-811dd84d"]]);
|
|
276
|
+
export {
|
|
277
|
+
ke as ProportionPlot
|
|
278
|
+
};
|