@qe-libs/qeviz 0.1.0

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/README.md ADDED
@@ -0,0 +1,187 @@
1
+ # qeviz
2
+
3
+ Interactive [Epistemic Network Analysis](https://www.epistemicnetwork.org/) (ENA) and Ordered Network Analysis (ONA) visualizations, implemented as framework-agnostic web components and wrapped for R, Python, and Julia.
4
+
5
+ ## Architecture
6
+
7
+ qeviz is a language-agnostic TypeScript web component library with thin adapter packages for each language:
8
+
9
+ ```
10
+ ┌─────────────────────────────────────────────┐
11
+ │ <qe-visual> / <qe-graph> │ TypeScript / browser
12
+ │ SVG rendering, edge networks, means, CI │ src/
13
+ └────────────────────┬────────────────────────┘
14
+ │ ModelData JSON
15
+ ┌───────────────┼───────────────┐
16
+ ▼ ▼ ▼
17
+ R adapter Python adapter Julia adapter
18
+ R/ py/ julia/
19
+ ```
20
+
21
+ Each adapter serialises model data to the qeviz `ModelData` format and produces self-contained HTML. The TypeScript layer has no knowledge of R, Python, or Julia.
22
+
23
+ ## Language bindings
24
+
25
+ ### R
26
+
27
+ ```r
28
+ library(qeviz)
29
+
30
+ # From a fitted rENA / tma set
31
+ qe_plot(set) |>
32
+ qe_group() |>
33
+ qe_edges("FirstGame", also = "SecondGame")
34
+
35
+ # Introspect
36
+ qe_groups(p) #> ["FirstGame", "SecondGame"]
37
+ qe_units(p) #> ["FirstGame::alice", ...]
38
+
39
+ # Individual unit network
40
+ qe_plot(set) |> qe_group() |> qe_edges(unit = "FirstGame::alice")
41
+
42
+ # Export
43
+ qe_export_html(p, "output.html")
44
+ ```
45
+
46
+ Install from [cran.qe-libs.org](https://cran.qe-libs.org):
47
+
48
+ ```r
49
+ install.packages("qeviz", repos = c("https://cran.qe-libs.org", "https://cloud.r-project.org"))
50
+ ```
51
+
52
+ ### Python
53
+
54
+ ```python
55
+ import qeviz
56
+
57
+ # From a fitted pyENA model
58
+ p = qeviz.from_pyena(model, group_col="Condition")
59
+
60
+ # Chain API
61
+ p.group("FirstGame").edges("FirstGame", also="SecondGame").points()
62
+
63
+ # Individual unit network
64
+ p.group().edges(unit="FirstGame::alice")
65
+
66
+ # Introspect
67
+ p.groups() # ["FirstGame", "SecondGame"]
68
+ p.units() # ["FirstGame::alice", ...]
69
+
70
+ # Jupyter inline display — just return p from a cell
71
+ p
72
+
73
+ # Export
74
+ p.export_html("output.html")
75
+ ```
76
+
77
+ Install from [py.qe-libs.org](https://py.qe-libs.org):
78
+
79
+ ```sh
80
+ pip install qeviz --extra-index-url https://py.qe-libs.org/simple
81
+ ```
82
+
83
+ ### Julia
84
+
85
+ ```julia
86
+ using QEViz
87
+
88
+ m = model_data(nodes_df, edges_df, points_df; group_col = "Condition")
89
+ p = qe_plot(m)
90
+
91
+ # Chain API
92
+ qe_group(p, "FirstGame") |> (x -> qe_edges(x; group = "FirstGame", also = "SecondGame"))
93
+
94
+ # Individual unit network
95
+ qe_edges(qe_group(p); unit = "FirstGame::alice")
96
+
97
+ # Introspect
98
+ qe_groups(p) # ["FirstGame", "SecondGame"]
99
+ qe_units(p) # ["FirstGame::alice", ...]
100
+
101
+ # Jupyter / Pluto — return p from a cell
102
+ p
103
+
104
+ # Export
105
+ qe_export_html(p, "output.html")
106
+ ```
107
+
108
+ ## Chain API
109
+
110
+ All three languages share the same chain operations:
111
+
112
+ | Operation | R | Python | Julia |
113
+ |---|---|---|---|
114
+ | Create | `qe_plot(set)` | `qeviz.plot(model)` | `qe_plot(model)` |
115
+ | Group means | `qe_group(p, ...)` | `p.group(...)` | `qe_group(p, ...)` |
116
+ | Edge network | `qe_edges(p, group=, unit=, compare=, also=)` | `p.edges(group=, unit=, ...)` | `qe_edges(p; group=, unit=, ...)` |
117
+ | Unit points | `qe_points(p)` | `p.points()` | `qe_points(p)` |
118
+ | Labels | `qe_labels(p, nodes=, means=, points=)` | `p.labels(...)` | `qe_labels(p; ...)` |
119
+ | Export | `qe_export_html(p, path)` | `p.export_html(path)` | `qe_export_html(p, path)` |
120
+ | Introspect | `qe_groups(p)` / `qe_units(p)` | `p.groups()` / `p.units()` | `qe_groups(p)` / `qe_units(p)` |
121
+
122
+ ### `qe_edges` / `.edges()` parameters
123
+
124
+ | Parameter | Description |
125
+ |---|---|
126
+ | `group` | Group name whose **mean** edge network to draw |
127
+ | `unit` | Unit ID for an **individual** network (e.g. `"FirstGame::alice"`). Mutually exclusive with `group`. |
128
+ | `compare` | Second group to subtract (`group − compare`). Positive differences use the primary colour. |
129
+ | `also` | Second group to overlay alongside `group`. |
130
+ | `show` / `show=false` | Suppress all edges. |
131
+
132
+ Label modes: `"on"`, `"off"`, `"click"`, `"auto"`.
133
+
134
+ ## TypeScript / web component
135
+
136
+ The `<qe-visual>` and `<qe-graph>` elements can be used directly in any HTML page. Layer configuration uses declarative child elements:
137
+
138
+ ```html
139
+ <script src="qeviz.umd.js"></script>
140
+
141
+ <qe-visual id="vis">
142
+ <qe-graph width="100%" height="440">
143
+ <qe-nodes label="on"></qe-nodes>
144
+ <qe-means confidence label="on"></qe-means>
145
+ <qe-points label="auto"></qe-points>
146
+ <qe-edges group="FirstGame" also="SecondGame"></qe-edges>
147
+ </qe-graph>
148
+ </qe-visual>
149
+
150
+ <script>
151
+ document.getElementById("vis").setModelData(modelJSON);
152
+ </script>
153
+ ```
154
+
155
+ Child element presence controls layer visibility — add `<qe-points>` to show unit dots, omit it to hide them. A `MutationObserver` watches for child additions, removals, and attribute changes, so interactive controls can manipulate the DOM directly:
156
+
157
+ ```js
158
+ // Switch to a subtraction plot
159
+ const edges = graph.querySelector("qe-edges");
160
+ edges.setAttribute("compare", "SecondGame");
161
+ edges.removeAttribute("also");
162
+ ```
163
+
164
+ ### Build
165
+
166
+ ```sh
167
+ npm install
168
+ npm run build # outputs dist/qeviz.umd.js and dist/qeviz.es.js
169
+ # postbuild copies the UMD bundle to R/inst/, py/qeviz/, julia/assets/
170
+ ```
171
+
172
+ ## Development
173
+
174
+ ```sh
175
+ # TypeScript
176
+ npm run dev # watch mode
177
+
178
+ # R (from project root)
179
+ pkgload::load_all("R")
180
+ testthat::test_local("R")
181
+
182
+ # Python
183
+ cd py && pip install -e ".[dev]" && pytest
184
+
185
+ # Julia
186
+ cd julia && julia --project=. -e 'using Pkg; Pkg.test()'
187
+ ```