allotaxonometer-ui 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 +51 -0
- package/dist/index.js +1094 -0
- package/dist/style.css +28 -0
- package/package.json +38 -0
package/README.md
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Allotaxonometer UI
|
|
2
|
+
|
|
3
|
+
Headless UI components for allotaxonometer visualizations built with Svelte 5.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install allotaxonometer-ui
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Make sure you have these installed:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install svelte d3 allotaxonometer @ungap/structured-clone
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
```svelte
|
|
20
|
+
<script>
|
|
21
|
+
import { Dashboard } from 'allotaxonometer-ui';
|
|
22
|
+
|
|
23
|
+
// Your data
|
|
24
|
+
let sys1 = [...];
|
|
25
|
+
let sys2 = [...];
|
|
26
|
+
</script>
|
|
27
|
+
|
|
28
|
+
<Dashboard
|
|
29
|
+
test_elem_1={sys1}
|
|
30
|
+
test_elem_2={sys2}
|
|
31
|
+
alpha={0.58}
|
|
32
|
+
title={['System 1', 'System 2']}
|
|
33
|
+
/>
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Components
|
|
37
|
+
|
|
38
|
+
- Dashboard - Complete dashboard with all visualizations
|
|
39
|
+
- Diamond - Diamond chart component
|
|
40
|
+
- Wordshift - Word shift visualization
|
|
41
|
+
- DivergingBarChart - Diverging bar chart
|
|
42
|
+
- Legend - Legend component
|
|
43
|
+
|
|
44
|
+
## Development
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
git clone https://github.com/yourusername/allotaxonometer-ui.git
|
|
48
|
+
cd allotaxonometer-ui
|
|
49
|
+
npm install
|
|
50
|
+
npm run build
|
|
51
|
+
```
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,1094 @@
|
|
|
1
|
+
import 'svelte/internal/disclose-version';
|
|
2
|
+
import * as $ from 'svelte/internal/client';
|
|
3
|
+
import * as d3 from 'd3';
|
|
4
|
+
import { extent, InternSet, range, rollup, scaleLinear, scaleBand, rgb, interpolateInferno, scaleOrdinal, max, scaleLog } from 'd3';
|
|
5
|
+
|
|
6
|
+
var root_1$7 = $.from_svg(`<g class="xtick"><line x1="0" x2="0" y1="0" y2="6" stroke="hsla(212, 10%, 53%, 1)"></line></g><g class="tick-text"><text font-size="10" dx="13" dy="13"> </text></g>`, 1);
|
|
7
|
+
var root$8 = $.from_svg(`<g class="axis x"><!><g class="xlab svelte-1y8xk6i"><text dy="45">Rank r</text><text dy="63">for</text><text dy="80"> </text><text dy="60" fill="hsla(212, 10%, 53%, 1)" opacity="0.7">more →</text><text dy="75" fill="hsla(212, 10%, 53%, 1)" opacity="0.7">frequent</text><text dy="60" fill="hsla(212, 10%, 53%, 1)" opacity="0.7">← less</text><text dy="75" fill="hsla(212, 10%, 53%, 1)" opacity="0.7">frequent</text></g></g>`);
|
|
8
|
+
|
|
9
|
+
function AxisX($$anchor, $$props) {
|
|
10
|
+
$.push($$props, true);
|
|
11
|
+
|
|
12
|
+
let logFormat10 = $$props.scale.tickFormat();
|
|
13
|
+
let xTicks = $$props.scale.ticks();
|
|
14
|
+
var g = root$8();
|
|
15
|
+
var node = $.child(g);
|
|
16
|
+
|
|
17
|
+
$.each(node, 17, () => xTicks, $.index, ($$anchor, tick) => {
|
|
18
|
+
var fragment = root_1$7();
|
|
19
|
+
var g_1 = $.first_child(fragment);
|
|
20
|
+
var g_2 = $.sibling(g_1);
|
|
21
|
+
var text = $.child(g_2);
|
|
22
|
+
var text_1 = $.child(text, true);
|
|
23
|
+
|
|
24
|
+
$.reset(text);
|
|
25
|
+
$.reset(g_2);
|
|
26
|
+
|
|
27
|
+
$.template_effect(
|
|
28
|
+
($0, $1, $2) => {
|
|
29
|
+
$.set_attribute(g_1, 'transform', `translate(${$0 ?? ''}, 0)`);
|
|
30
|
+
$.set_attribute(g_2, 'transform', `translate(${$1 ?? ''}, 0) scale(-1,1) rotate(45)`);
|
|
31
|
+
$.set_text(text_1, $2);
|
|
32
|
+
},
|
|
33
|
+
[
|
|
34
|
+
() => $$props.scale($.get(tick)),
|
|
35
|
+
() => $$props.scale($.get(tick)),
|
|
36
|
+
() => logFormat10($.get(tick))
|
|
37
|
+
]
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
$.append($$anchor, fragment);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
var g_3 = $.sibling(node);
|
|
44
|
+
var text_2 = $.child(g_3);
|
|
45
|
+
var text_3 = $.sibling(text_2);
|
|
46
|
+
var text_4 = $.sibling(text_3);
|
|
47
|
+
var text_5 = $.child(text_4, true);
|
|
48
|
+
|
|
49
|
+
$.reset(text_4);
|
|
50
|
+
|
|
51
|
+
var text_6 = $.sibling(text_4);
|
|
52
|
+
var text_7 = $.sibling(text_6);
|
|
53
|
+
var text_8 = $.sibling(text_7);
|
|
54
|
+
|
|
55
|
+
$.set_attribute(text_8, 'x', 40);
|
|
56
|
+
|
|
57
|
+
var text_9 = $.sibling(text_8);
|
|
58
|
+
|
|
59
|
+
$.set_attribute(text_9, 'x', 40);
|
|
60
|
+
$.reset(g_3);
|
|
61
|
+
$.reset(g);
|
|
62
|
+
|
|
63
|
+
$.template_effect(() => {
|
|
64
|
+
$.set_attribute(g, 'transform', `translate(0, ${$$props.height ?? ''})`);
|
|
65
|
+
$.set_attribute(g_3, 'transform', `scale(-1,1) translate(-${$$props.height ?? ''}, 0)`);
|
|
66
|
+
$.set_attribute(text_2, 'x', $$props.height / 2);
|
|
67
|
+
$.set_attribute(text_3, 'x', $$props.height / 2);
|
|
68
|
+
$.set_attribute(text_4, 'x', $$props.height / 2);
|
|
69
|
+
$.set_text(text_5, $$props.title[1]);
|
|
70
|
+
$.set_attribute(text_6, 'x', $$props.height - 40);
|
|
71
|
+
$.set_attribute(text_7, 'x', $$props.height - 40);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
$.append($$anchor, g);
|
|
75
|
+
$.pop();
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
var root_1$6 = $.from_svg(`<g class="ytick"><line x1="0" x2="-6" y1="0" y2="0" stroke="hsla(212, 10%, 53%, 1)"></line></g><g class="tick-text"><text font-size="10" dx="-23" dy="10"> </text></g>`, 1);
|
|
79
|
+
var root$7 = $.from_svg(`<g class="axis y"><!><g class="ylab svelte-1y8visx" transform="rotate(90)"><text dy="45">Rank r</text><text dy="63">for</text><text dy="80"> </text><text dy="60" fill="hsla(212, 10%, 53%, 1)" opacity="0.7">more →</text><text dy="75" fill="hsla(212, 10%, 53%, 1)" opacity="0.7">frequent</text><text dy="60" fill="hsla(212, 10%, 53%, 1)" opacity="0.7">← less</text><text dy="75" fill="hsla(212, 10%, 53%, 1)" opacity="0.7">frequent</text></g></g>`);
|
|
80
|
+
|
|
81
|
+
function AxisY($$anchor, $$props) {
|
|
82
|
+
$.push($$props, true);
|
|
83
|
+
|
|
84
|
+
let logFormat10 = $$props.scale.tickFormat();
|
|
85
|
+
let yTicks = $.derived(() => $$props.scale.ticks());
|
|
86
|
+
var g = root$7();
|
|
87
|
+
var node = $.child(g);
|
|
88
|
+
|
|
89
|
+
$.each(node, 17, () => $.get(yTicks), $.index, ($$anchor, tick) => {
|
|
90
|
+
var fragment = root_1$6();
|
|
91
|
+
var g_1 = $.first_child(fragment);
|
|
92
|
+
var g_2 = $.sibling(g_1);
|
|
93
|
+
var text = $.child(g_2);
|
|
94
|
+
var text_1 = $.child(text, true);
|
|
95
|
+
|
|
96
|
+
$.reset(text);
|
|
97
|
+
$.reset(g_2);
|
|
98
|
+
|
|
99
|
+
$.template_effect(
|
|
100
|
+
($0, $1, $2) => {
|
|
101
|
+
$.set_attribute(g_1, 'transform', `translate(0, ${$0 ?? ''})`);
|
|
102
|
+
$.set_attribute(g_2, 'transform', `translate(0, ${$1 ?? ''}) rotate(45)`);
|
|
103
|
+
$.set_text(text_1, $2);
|
|
104
|
+
},
|
|
105
|
+
[
|
|
106
|
+
() => $$props.scale($.get(tick)),
|
|
107
|
+
() => $$props.scale($.get(tick)),
|
|
108
|
+
() => logFormat10($.get(tick))
|
|
109
|
+
]
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
$.append($$anchor, fragment);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
var g_3 = $.sibling(node);
|
|
116
|
+
var text_2 = $.child(g_3);
|
|
117
|
+
var text_3 = $.sibling(text_2);
|
|
118
|
+
var text_4 = $.sibling(text_3);
|
|
119
|
+
var text_5 = $.child(text_4, true);
|
|
120
|
+
|
|
121
|
+
$.reset(text_4);
|
|
122
|
+
|
|
123
|
+
var text_6 = $.sibling(text_4);
|
|
124
|
+
var text_7 = $.sibling(text_6);
|
|
125
|
+
var text_8 = $.sibling(text_7);
|
|
126
|
+
|
|
127
|
+
$.set_attribute(text_8, 'x', 40);
|
|
128
|
+
|
|
129
|
+
var text_9 = $.sibling(text_8);
|
|
130
|
+
|
|
131
|
+
$.set_attribute(text_9, 'x', 40);
|
|
132
|
+
$.reset(g_3);
|
|
133
|
+
$.reset(g);
|
|
134
|
+
|
|
135
|
+
$.template_effect(() => {
|
|
136
|
+
$.set_attribute(g, 'transform', `translate(${$$props.height ?? ''}, 0) scale(-1, 1)`);
|
|
137
|
+
$.set_attribute(text_2, 'x', $$props.height / 2);
|
|
138
|
+
$.set_attribute(text_3, 'x', $$props.height / 2);
|
|
139
|
+
$.set_attribute(text_4, 'x', $$props.height / 2);
|
|
140
|
+
$.set_text(text_5, $$props.title[0]);
|
|
141
|
+
$.set_attribute(text_6, 'x', $$props.height - 40);
|
|
142
|
+
$.set_attribute(text_7, 'x', $$props.height - 40);
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
$.append($$anchor, g);
|
|
146
|
+
$.pop();
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
var root_1$5 = $.from_svg(`<g><line y2="0" stroke="#d3d3d3" stroke-dasharray="3,3"></line></g><g><line x2="0" stroke="#d3d3d3" stroke-dasharray="3,3"></line></g>`, 1);
|
|
150
|
+
var root$6 = $.from_svg(`<g class="grid"></g>`);
|
|
151
|
+
|
|
152
|
+
function Grid($$anchor, $$props) {
|
|
153
|
+
$.push($$props, true);
|
|
154
|
+
|
|
155
|
+
let xygridLines = $.derived(() => $$props.scale.ticks($$props.ncells / 2));
|
|
156
|
+
var g = root$6();
|
|
157
|
+
|
|
158
|
+
$.each(g, 21, () => $.get(xygridLines), $.index, ($$anchor, yline, index) => {
|
|
159
|
+
var fragment = root_1$5();
|
|
160
|
+
var g_1 = $.first_child(fragment);
|
|
161
|
+
var line = $.child(g_1);
|
|
162
|
+
|
|
163
|
+
$.set_attribute(line, 'opacity', index === 0 ? 0 : 1);
|
|
164
|
+
$.reset(g_1);
|
|
165
|
+
|
|
166
|
+
var g_2 = $.sibling(g_1);
|
|
167
|
+
var line_1 = $.child(g_2);
|
|
168
|
+
|
|
169
|
+
$.set_attribute(line_1, 'opacity', index === 0 ? 0 : 1);
|
|
170
|
+
$.reset(g_2);
|
|
171
|
+
|
|
172
|
+
$.template_effect(
|
|
173
|
+
($0, $1) => {
|
|
174
|
+
$.set_attribute(g_1, 'transform', `translate(${$0 ?? ''}, 0)`);
|
|
175
|
+
$.set_attribute(line, 'y1', $$props.height);
|
|
176
|
+
$.set_attribute(g_2, 'transform', `translate(0, ${$1 ?? ''})`);
|
|
177
|
+
$.set_attribute(line_1, 'x1', $$props.height);
|
|
178
|
+
},
|
|
179
|
+
[
|
|
180
|
+
() => $$props.wxy($.get(yline)),
|
|
181
|
+
() => $$props.wxy($.get(yline))
|
|
182
|
+
]
|
|
183
|
+
);
|
|
184
|
+
|
|
185
|
+
$.append($$anchor, fragment);
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
$.reset(g);
|
|
189
|
+
$.append($$anchor, g);
|
|
190
|
+
$.pop();
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
var root_1$4 = $.from_svg(`<g><path fill="none" stroke="grey" stroke-width="0.9" stroke-opacity="0.9"></path></g>`);
|
|
194
|
+
var root$5 = $.from_svg(`<g class="contours"></g>`);
|
|
195
|
+
|
|
196
|
+
function Contours($$anchor, $$props) {
|
|
197
|
+
$.push($$props, true);
|
|
198
|
+
|
|
199
|
+
function alpha_norm_type2(x1, x2, alpha) {
|
|
200
|
+
if (alpha == 0) {
|
|
201
|
+
return Math.abs(Math.log(x1 / x2));
|
|
202
|
+
} else if (alpha === Infinity) {
|
|
203
|
+
return x1 === x2 ? 0 : Math.max(x1, x2);
|
|
204
|
+
} else {
|
|
205
|
+
const prefactor = (alpha + 1) / alpha;
|
|
206
|
+
const power = 1 / (alpha + 1);
|
|
207
|
+
|
|
208
|
+
return prefactor * Math.abs(Math.pow(x1, alpha) - Math.pow(x2, alpha)) ** power;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
function make_grid(Ninset, tmpr1, tmpr2, alpha, rtd) {
|
|
213
|
+
// No matrix in js :(
|
|
214
|
+
// we could try to do like in the original d3.contour, where they do
|
|
215
|
+
// calculation to work with a flat array.
|
|
216
|
+
// Instead we flatten that List of list later.
|
|
217
|
+
const deltamatrix = Array.from({ length: Ninset }, () => Array(Ninset).fill(0));
|
|
218
|
+
|
|
219
|
+
// Populate deltamatrix with alpha_norm_type2 values and set the diagonal and adjacent values
|
|
220
|
+
for (let i = 0; i < Ninset; i++) {
|
|
221
|
+
for (let j = 0; j < Ninset; j++) {
|
|
222
|
+
const divElem = alpha_norm_type2(1 / tmpr1[i], 1 / tmpr2[j], alpha);
|
|
223
|
+
|
|
224
|
+
deltamatrix[i][j] = divElem / rtd.normalization;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// %% prevent contours from crossing the center line
|
|
228
|
+
deltamatrix[i][i] = -1;
|
|
229
|
+
|
|
230
|
+
// Set adjacent diagonal elements to -1 if within bounds
|
|
231
|
+
if (i < Ninset - 1) {
|
|
232
|
+
deltamatrix[i][i + 1] = -1;
|
|
233
|
+
deltamatrix[i + 1][i] = -1;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
return deltamatrix;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
function filter_contours(tmpcontours, Ninset, maxlog10) {
|
|
241
|
+
const chart2val = d3.scaleLinear().domain([0, Ninset]).range([
|
|
242
|
+
0, // unit: km
|
|
243
|
+
maxlog10
|
|
244
|
+
]); // unit: pixels
|
|
245
|
+
|
|
246
|
+
let out = [];
|
|
247
|
+
|
|
248
|
+
// Extract Coordinates:
|
|
249
|
+
tmpcontours.forEach((contour) => {
|
|
250
|
+
contour.coordinates.forEach((pair, i) => {
|
|
251
|
+
const tmpr1 = pair[0].map((d) => d[0]); // x-coordinates
|
|
252
|
+
const tmpr2 = pair[0].map((d) => d[1]); // y-coordinates
|
|
253
|
+
// Array to store filtered coordinate pairs in zipped format
|
|
254
|
+
const filteredPairs = [];
|
|
255
|
+
|
|
256
|
+
// Loop through each coordinate and calculate `tmpxrot`
|
|
257
|
+
for (let index = 0; index < tmpr1.length - 1; index++) {
|
|
258
|
+
const x1 = chart2val(tmpr1[index]);
|
|
259
|
+
const x2 = chart2val(tmpr2[index]);
|
|
260
|
+
// Calculate tmpxrot
|
|
261
|
+
const tmpxrot = Math.abs(x2 - x1) / Math.sqrt(2);
|
|
262
|
+
|
|
263
|
+
// If the condition is met, add the coordinate pair [x1, x2] to `filteredPairs`
|
|
264
|
+
if (Math.abs(tmpxrot) >= 0.1 & x1 != maxlog10 & x2 != 0 & x1 != 0 & x2 != maxlog10) {
|
|
265
|
+
filteredPairs.push([x1, x2]);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// Only push to `out` if we have filtered pairs
|
|
270
|
+
if (filteredPairs.length > 0) {
|
|
271
|
+
out.push(filteredPairs); // Store each set of filtered pairs in `out`
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
return out;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
function get_contours(alpha, maxlog10) {
|
|
280
|
+
// only for alpha != 0 and alpha != Infinity
|
|
281
|
+
const Ninset = 10 ** 3;
|
|
282
|
+
const tmpr1 = d3.range(0, 1000).map((d) => Math.pow(10, d / 999 * 5));
|
|
283
|
+
const tmpr2 = d3.range(0, 1000).map((d) => Math.pow(10, d / 999 * 5));
|
|
284
|
+
// Create a scale to generate `Ncontours + 2` values linearly spaced between 1 and `tmpr1Length`
|
|
285
|
+
const Ncontours = 10;
|
|
286
|
+
const scale = d3.scaleLinear().domain([0, Ncontours + 1]).range([1, tmpr1.length]);
|
|
287
|
+
const contour_indices = d3.range(Ncontours + 2).map((i) => Math.round(scale(i)));
|
|
288
|
+
const grid = make_grid(Ninset, tmpr1, tmpr2, alpha, $$props.rtd);
|
|
289
|
+
const indices = contour_indices.slice(1, -1);
|
|
290
|
+
const lastRow = grid[grid.length - 1];
|
|
291
|
+
const heights = indices.map((index) => lastRow[index]);
|
|
292
|
+
// equivalent to `contourc`
|
|
293
|
+
// we first create a generator
|
|
294
|
+
// then we pass to Z (flatDeltamatrix)
|
|
295
|
+
const logTmpr = tmpr1.map(Math.log10);
|
|
296
|
+
const contourGenerator = d3.contours().size([logTmpr.length, logTmpr.length]).thresholds(heights); // Set the grid size
|
|
297
|
+
// I guess this is equivalent? These are levels.
|
|
298
|
+
const flatDeltamatrix = grid.flat();
|
|
299
|
+
const tmpcontours = contourGenerator(flatDeltamatrix);
|
|
300
|
+
|
|
301
|
+
return filter_contours(tmpcontours, Ninset, maxlog10);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
let mycontours = $.derived(() => get_contours($$props.alpha, $$props.maxlog10));
|
|
305
|
+
const x = $.derived(() => d3.scaleLinear([0, $$props.maxlog10], [0, $$props.DiamondInnerHeight]));
|
|
306
|
+
const y = $.derived(() => d3.scaleLinear([$$props.maxlog10, 0], [$$props.DiamondInnerHeight, 0]));
|
|
307
|
+
const pathData = d3.line().x((d, i) => $.get(x)(d[0])).y((d, i) => $.get(y)(d[1]));
|
|
308
|
+
var g = root$5();
|
|
309
|
+
|
|
310
|
+
$.each(g, 21, () => $.get(mycontours), $.index, ($$anchor, contour) => {
|
|
311
|
+
var g_1 = root_1$4();
|
|
312
|
+
var path = $.child(g_1);
|
|
313
|
+
|
|
314
|
+
$.reset(g_1);
|
|
315
|
+
|
|
316
|
+
$.template_effect(
|
|
317
|
+
($0, $1, $2) => {
|
|
318
|
+
$.set_attribute(g_1, 'transform', `translate(${$0 ?? ''}, ${$1 ?? ''})`);
|
|
319
|
+
$.set_attribute(path, 'd', $2);
|
|
320
|
+
},
|
|
321
|
+
[
|
|
322
|
+
() => $.get(x)($.get(contour)),
|
|
323
|
+
() => $.get(y)($.get(contour)),
|
|
324
|
+
() => pathData($.get(contour))
|
|
325
|
+
]
|
|
326
|
+
);
|
|
327
|
+
|
|
328
|
+
$.append($$anchor, g_1);
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
$.reset(g);
|
|
332
|
+
$.append($$anchor, g);
|
|
333
|
+
$.pop();
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
var root_1$3 = $.from_svg(`<rect stroke="black" stroke-width="0.2"></rect>`);
|
|
337
|
+
var root_2$3 = $.from_svg(`<g class="diamond-lab"><text font-size="10"> </text></g>`);
|
|
338
|
+
var root$4 = $.from_svg(`<g class="diamond-chart"><polygon fill="#89CFF0" fill-opacity="0.2" stroke="black" stroke-width="0.5"></polygon><polygon fill="grey" fill-opacity="0.2" stroke="black" stroke-width="0.5"></polygon><!><!><!><!><!><!></g>`);
|
|
339
|
+
|
|
340
|
+
function Diamond($$anchor, $$props) {
|
|
341
|
+
$.push($$props, true);
|
|
342
|
+
|
|
343
|
+
function get_relevant_types(diamond_dat) {
|
|
344
|
+
const ncells = 60;
|
|
345
|
+
const bin_size = 1.5;
|
|
346
|
+
const cummulative_bin = d3.range(0, ncells, bin_size);
|
|
347
|
+
const relevant_types = [];
|
|
348
|
+
|
|
349
|
+
for (let sys of ["right", "left"]) {
|
|
350
|
+
for (let i = 1; i < cummulative_bin.length; i++) {
|
|
351
|
+
const filtered_dat = diamond_dat.filter((d) => d.value > 0 && d.which_sys == sys).filter((d) => d.coord_on_diag >= cummulative_bin[i - 1] && d.coord_on_diag < cummulative_bin[i]);
|
|
352
|
+
|
|
353
|
+
if (filtered_dat.length > 0) {
|
|
354
|
+
const cos_dists = filtered_dat.map((d) => d.cos_dist);
|
|
355
|
+
|
|
356
|
+
const max_dist = cos_dists.reduce((a, b) => {
|
|
357
|
+
return Math.max(a, b);
|
|
358
|
+
});
|
|
359
|
+
|
|
360
|
+
const max_dist_idx = cos_dists.indexOf(max_dist);
|
|
361
|
+
const name = d3.shuffle(filtered_dat[max_dist_idx]['types'].split(","))[0];
|
|
362
|
+
|
|
363
|
+
relevant_types.push(name);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
return relevant_types;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
function rin(arr1, arr2) {
|
|
372
|
+
// Find element arr1 presents in arr2, i.e. arr1 %in% arr2
|
|
373
|
+
//
|
|
374
|
+
// examples
|
|
375
|
+
// A = ["bob", "george", "jesus"]
|
|
376
|
+
// B = ["bob", "jesus", "terrence"]
|
|
377
|
+
// rin(A, B)
|
|
378
|
+
// [true, false, true]
|
|
379
|
+
return Array.from(arr1, (x) => {
|
|
380
|
+
return arr2.indexOf(x) == -1 ? false : true;
|
|
381
|
+
});
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
// Wrangling data
|
|
385
|
+
let relevant_types = $.derived(() => get_relevant_types($$props.diamond_dat));
|
|
386
|
+
// Extracting constant
|
|
387
|
+
let max_rank_raw = $.derived(() => d3.range(d3.max($$props.diamond_count, (d) => d.x1)));
|
|
388
|
+
let max_rank = $.derived(() => d3.max($$props.diamond_dat, (d) => d.rank_L[1]));
|
|
389
|
+
let rounded_max_rank = $.derived(() => 10 ** Math.ceil(Math.max(Math.log10($.get(max_rank)))));
|
|
390
|
+
let ncells = $.derived(() => d3.max($.get(max_rank_raw)));
|
|
391
|
+
let xyDomain = $.derived(() => [1, $.get(rounded_max_rank)]);
|
|
392
|
+
// All the Scales!
|
|
393
|
+
let linScale = $.derived(() => d3.scaleLinear().domain([0, $.get(ncells) - 1]).range([0, $$props.DiamondInnerHeight]));
|
|
394
|
+
let wxy = $.derived(() => d3.scaleBand().domain($.get(max_rank_raw)).range([0, $$props.DiamondInnerHeight]));
|
|
395
|
+
let logScale = $.derived(() => d3.scaleLog().domain($.get(xyDomain)).range([0, $$props.DiamondInnerHeight]).nice());
|
|
396
|
+
let xy = $.derived(() => d3.scaleBand().domain($.get(max_rank_raw)).range([0, $$props.trueDiamondHeight]));
|
|
397
|
+
let color_scale = d3.scaleSequentialLog().domain([$.get(rounded_max_rank), 1]).interpolator(d3.interpolateInferno);
|
|
398
|
+
|
|
399
|
+
// Background colors
|
|
400
|
+
let blue_triangle = [
|
|
401
|
+
[
|
|
402
|
+
$$props.DiamondInnerHeight,
|
|
403
|
+
$$props.DiamondInnerHeight
|
|
404
|
+
],
|
|
405
|
+
[0, 0],
|
|
406
|
+
[0, $$props.DiamondInnerHeight]
|
|
407
|
+
].join(" ");
|
|
408
|
+
|
|
409
|
+
let grey_triangle = [
|
|
410
|
+
[
|
|
411
|
+
$$props.DiamondInnerHeight,
|
|
412
|
+
$$props.DiamondInnerHeight
|
|
413
|
+
],
|
|
414
|
+
[0, 0],
|
|
415
|
+
[$$props.DiamondInnerHeight, 0]
|
|
416
|
+
].join(" ");
|
|
417
|
+
|
|
418
|
+
function filter_labs(d, relevant_types) {
|
|
419
|
+
return rin(relevant_types, d.types.split(",")).some((x) => x === true);
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
var g = root$4();
|
|
423
|
+
var polygon = $.child(g);
|
|
424
|
+
var polygon_1 = $.sibling(polygon);
|
|
425
|
+
var node = $.sibling(polygon_1);
|
|
426
|
+
|
|
427
|
+
AxisX(node, {
|
|
428
|
+
get height() {
|
|
429
|
+
return $$props.DiamondInnerHeight;
|
|
430
|
+
},
|
|
431
|
+
get scale() {
|
|
432
|
+
return $.get(logScale);
|
|
433
|
+
},
|
|
434
|
+
get title() {
|
|
435
|
+
return $$props.title;
|
|
436
|
+
}
|
|
437
|
+
});
|
|
438
|
+
|
|
439
|
+
var node_1 = $.sibling(node);
|
|
440
|
+
|
|
441
|
+
AxisY(node_1, {
|
|
442
|
+
get height() {
|
|
443
|
+
return $$props.DiamondInnerHeight;
|
|
444
|
+
},
|
|
445
|
+
get scale() {
|
|
446
|
+
return $.get(logScale);
|
|
447
|
+
},
|
|
448
|
+
get title() {
|
|
449
|
+
return $$props.title;
|
|
450
|
+
}
|
|
451
|
+
});
|
|
452
|
+
|
|
453
|
+
var node_2 = $.sibling(node_1);
|
|
454
|
+
|
|
455
|
+
Grid(node_2, {
|
|
456
|
+
get height() {
|
|
457
|
+
return $$props.DiamondInnerHeight;
|
|
458
|
+
},
|
|
459
|
+
get wxy() {
|
|
460
|
+
return $.get(wxy);
|
|
461
|
+
},
|
|
462
|
+
get ncells() {
|
|
463
|
+
return $.get(ncells);
|
|
464
|
+
},
|
|
465
|
+
get scale() {
|
|
466
|
+
return $.get(linScale);
|
|
467
|
+
}
|
|
468
|
+
});
|
|
469
|
+
|
|
470
|
+
var node_3 = $.sibling(node_2);
|
|
471
|
+
|
|
472
|
+
$.each(node_3, 17, () => $$props.diamond_dat, $.index, ($$anchor, d) => {
|
|
473
|
+
var rect = root_1$3();
|
|
474
|
+
|
|
475
|
+
$.template_effect(
|
|
476
|
+
($0, $1, $2, $3, $4) => {
|
|
477
|
+
$.set_attribute(rect, 'x', $0);
|
|
478
|
+
$.set_attribute(rect, 'y', $1);
|
|
479
|
+
$.set_attribute(rect, 'width', $2);
|
|
480
|
+
$.set_attribute(rect, 'height', $3);
|
|
481
|
+
$.set_attribute(rect, 'fill', $4);
|
|
482
|
+
$.set_attribute(rect, 'opacity', $.get(d).value === null ? 0 : 1.);
|
|
483
|
+
},
|
|
484
|
+
[
|
|
485
|
+
() => $.get(xy)($.get(d).x1),
|
|
486
|
+
() => $.get(xy)($.get(d).y1),
|
|
487
|
+
() => $.get(xy).bandwidth(),
|
|
488
|
+
() => $.get(xy).bandwidth(),
|
|
489
|
+
() => color_scale($.get(d).value)
|
|
490
|
+
]
|
|
491
|
+
);
|
|
492
|
+
|
|
493
|
+
$.append($$anchor, rect);
|
|
494
|
+
});
|
|
495
|
+
|
|
496
|
+
var node_4 = $.sibling(node_3);
|
|
497
|
+
|
|
498
|
+
$.each(node_4, 17, () => $$props.diamond_dat.filter((d) => filter_labs(d, $.get(relevant_types))), $.index, ($$anchor, d) => {
|
|
499
|
+
var g_1 = root_2$3();
|
|
500
|
+
var text = $.child(g_1);
|
|
501
|
+
|
|
502
|
+
$.set_attribute(text, 'dy', 20);
|
|
503
|
+
|
|
504
|
+
var text_1 = $.child(text, true);
|
|
505
|
+
|
|
506
|
+
$.reset(text);
|
|
507
|
+
$.reset(g_1);
|
|
508
|
+
|
|
509
|
+
$.template_effect(
|
|
510
|
+
($0, $1, $2, $3, $4, $5) => {
|
|
511
|
+
$.set_attribute(g_1, 'transform', `
|
|
512
|
+
scale(1,-1)
|
|
513
|
+
rotate(-90)
|
|
514
|
+
rotate(-45, ${$0 ?? ''}, ${$1 ?? ''})
|
|
515
|
+
translate(${$2 ?? ''}, 0)
|
|
516
|
+
`);
|
|
517
|
+
|
|
518
|
+
$.set_attribute(text, 'x', $3);
|
|
519
|
+
$.set_attribute(text, 'y', $4);
|
|
520
|
+
$.set_attribute(text, 'text-anchor', $.get(d).x1 - $.get(d).y1 <= 0 ? "start" : "end");
|
|
521
|
+
$.set_text(text_1, $5);
|
|
522
|
+
},
|
|
523
|
+
[
|
|
524
|
+
() => $.get(xy)($.get(d).x1),
|
|
525
|
+
() => $.get(xy)($.get(d).y1),
|
|
526
|
+
() => $.get(d).which_sys === "right" ? $.get(xy)(Math.sqrt($.get(d).cos_dist)) * 1.5 : -$.get(xy)(Math.sqrt($.get(d).cos_dist)) * 1.5,
|
|
527
|
+
() => $.get(xy)($.get(d).x1),
|
|
528
|
+
() => Number.isInteger($.get(d).coord_on_diag) ? $.get(xy)($.get(d).y1) : $.get(xy)($.get(d).y1) - 1,
|
|
529
|
+
() => $.get(d).types.split(",")[0]
|
|
530
|
+
]
|
|
531
|
+
);
|
|
532
|
+
|
|
533
|
+
$.append($$anchor, g_1);
|
|
534
|
+
});
|
|
535
|
+
|
|
536
|
+
var node_5 = $.sibling(node_4);
|
|
537
|
+
|
|
538
|
+
Contours(node_5, {
|
|
539
|
+
get alpha() {
|
|
540
|
+
return $$props.alpha;
|
|
541
|
+
},
|
|
542
|
+
get maxlog10() {
|
|
543
|
+
return $$props.maxlog10;
|
|
544
|
+
},
|
|
545
|
+
get rtd() {
|
|
546
|
+
return $$props.rtd;
|
|
547
|
+
},
|
|
548
|
+
get DiamondInnerHeight() {
|
|
549
|
+
return $$props.DiamondInnerHeight;
|
|
550
|
+
}
|
|
551
|
+
});
|
|
552
|
+
|
|
553
|
+
$.reset(g);
|
|
554
|
+
|
|
555
|
+
$.template_effect(() => {
|
|
556
|
+
$.set_attribute(g, 'transform', `translate(360, 0) scale (-1,1) rotate(45) translate(${$$props.margin.inner / 2}, ${$$props.margin.inner / 2})`);
|
|
557
|
+
$.set_attribute(polygon, 'points', blue_triangle);
|
|
558
|
+
$.set_attribute(polygon_1, 'points', grey_triangle);
|
|
559
|
+
});
|
|
560
|
+
|
|
561
|
+
$.append($$anchor, g);
|
|
562
|
+
$.pop();
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
var root_1$2 = $.from_svg(`<g class="tick"><line y1="0" stroke="hsla(212, 10%, 53%, 1)" stroke-opacity="0.2"> </line><text y="-12" font-size="0.8em"> </text></g>`);
|
|
566
|
+
var root_2$2 = $.from_svg(`<rect></rect><text dy="14" font-size="0.7em"> </text>`, 1);
|
|
567
|
+
var root$3 = $.from_svg(`<g class="barChart-container svelte-37sv8o"><g class="axis x"></g><!></g>`);
|
|
568
|
+
|
|
569
|
+
function Wordshift($$anchor, $$props) {
|
|
570
|
+
$.push($$props, true);
|
|
571
|
+
|
|
572
|
+
let margin = { top: 80, left: 140, right: 50, bottom: 10 };
|
|
573
|
+
let width = 640;
|
|
574
|
+
let yPadding = 0.2;
|
|
575
|
+
let Y = $.derived(() => d3.map($$props.barData, (d) => d.type));
|
|
576
|
+
let max_shift = $.derived(() => d3.max($$props.barData, (d) => Math.abs(d.metric)) * 1.5);
|
|
577
|
+
let xDomain = $.derived(() => [-$.get(max_shift), $.get(max_shift)]);
|
|
578
|
+
let yDomain = $.derived(() => new d3.InternSet($.get(Y)));
|
|
579
|
+
|
|
580
|
+
let xRange = $.derived(() => [
|
|
581
|
+
$$props.DashboardWidth - width + margin.left,
|
|
582
|
+
$$props.DashboardWidth - margin.right
|
|
583
|
+
]);
|
|
584
|
+
|
|
585
|
+
let yRange = $.derived(() => [
|
|
586
|
+
margin.top,
|
|
587
|
+
$$props.DashboardHeight - margin.bottom
|
|
588
|
+
]);
|
|
589
|
+
|
|
590
|
+
let xScale = $.derived(() => d3.scaleLinear().domain($.get(xDomain)).range($.get(xRange)));
|
|
591
|
+
let yScale = $.derived(() => d3.scaleBand($.get(yDomain), $.get(yRange)).padding(yPadding));
|
|
592
|
+
let xTicks = $.derived(() => $.get(xScale).ticks(width / 80));
|
|
593
|
+
const colors = ["lightgrey", "lightblue"];
|
|
594
|
+
var g = root$3();
|
|
595
|
+
var g_1 = $.child(g);
|
|
596
|
+
|
|
597
|
+
$.each(g_1, 21, () => $.get(xTicks), $.index, ($$anchor, tick) => {
|
|
598
|
+
var g_2 = root_1$2();
|
|
599
|
+
var line = $.child(g_2);
|
|
600
|
+
var text = $.child(line, true);
|
|
601
|
+
|
|
602
|
+
$.reset(line);
|
|
603
|
+
|
|
604
|
+
var text_1 = $.sibling(line);
|
|
605
|
+
var text_2 = $.child(text_1);
|
|
606
|
+
|
|
607
|
+
$.reset(text_1);
|
|
608
|
+
$.reset(g_2);
|
|
609
|
+
|
|
610
|
+
$.template_effect(
|
|
611
|
+
($0, $1, $2) => {
|
|
612
|
+
$.set_attribute(line, 'x1', $0);
|
|
613
|
+
$.set_attribute(line, 'x2', $1);
|
|
614
|
+
$.set_attribute(line, 'y2', $$props.DashboardHeight - margin.top - margin.bottom);
|
|
615
|
+
$.set_text(text, $.get(tick));
|
|
616
|
+
$.set_attribute(text_1, 'x', $2);
|
|
617
|
+
$.set_text(text_2, `${$.get(tick) * 100}%`);
|
|
618
|
+
},
|
|
619
|
+
[
|
|
620
|
+
() => $.get(xScale)($.get(tick)),
|
|
621
|
+
() => $.get(xScale)($.get(tick)),
|
|
622
|
+
() => $.get(xScale)($.get(tick))
|
|
623
|
+
]
|
|
624
|
+
);
|
|
625
|
+
|
|
626
|
+
$.append($$anchor, g_2);
|
|
627
|
+
});
|
|
628
|
+
|
|
629
|
+
$.reset(g_1);
|
|
630
|
+
|
|
631
|
+
var node = $.sibling(g_1);
|
|
632
|
+
|
|
633
|
+
$.each(node, 17, () => $$props.barData, $.index, ($$anchor, d) => {
|
|
634
|
+
var fragment = root_2$2();
|
|
635
|
+
var rect = $.first_child(fragment);
|
|
636
|
+
var text_3 = $.sibling(rect);
|
|
637
|
+
var text_4 = $.child(text_3, true);
|
|
638
|
+
|
|
639
|
+
$.reset(text_3);
|
|
640
|
+
|
|
641
|
+
$.template_effect(
|
|
642
|
+
($0, $1, $2, $3, $4, $5) => {
|
|
643
|
+
$.set_attribute(rect, 'x', $0);
|
|
644
|
+
$.set_attribute(rect, 'y', $1);
|
|
645
|
+
$.set_attribute(rect, 'fill', colors[$.get(d).metric > 0 ? colors.length - 1 : 0]);
|
|
646
|
+
$.set_attribute(rect, 'width', $2);
|
|
647
|
+
$.set_attribute(rect, 'height', $3);
|
|
648
|
+
$.set_attribute(text_3, 'x', $4);
|
|
649
|
+
$.set_attribute(text_3, 'y', $5);
|
|
650
|
+
$.set_text(text_4, $.get(d).type);
|
|
651
|
+
},
|
|
652
|
+
[
|
|
653
|
+
() => Math.min($.get(xScale)(0), $.get(xScale)($.get(d).metric)),
|
|
654
|
+
() => $.get(yScale)($.get(d).type),
|
|
655
|
+
() => Math.abs($.get(xScale)($.get(d).metric) - $.get(xScale)(0)),
|
|
656
|
+
() => $.get(yScale).bandwidth(),
|
|
657
|
+
() => Math.min($.get(xScale)(0), $.get(xScale)($.get(d).metric)),
|
|
658
|
+
() => $.get(yScale)($.get(d).type)
|
|
659
|
+
]
|
|
660
|
+
);
|
|
661
|
+
|
|
662
|
+
$.append($$anchor, fragment);
|
|
663
|
+
});
|
|
664
|
+
|
|
665
|
+
$.reset(g);
|
|
666
|
+
$.template_effect(() => $.set_attribute(g_1, 'transform', `translate(0, ${margin.top})`));
|
|
667
|
+
$.append($$anchor, g);
|
|
668
|
+
$.pop();
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
var root_1$1 = $.from_svg(`<rect></rect><text opacity="0.5" dy="0.35em" font-size="10"> </text>`, 1);
|
|
672
|
+
var root_2$1 = $.from_svg(`<g class="diverging-ticks"><text dy="-.9em" dx="-3em" font-size="10"> </text></g>`);
|
|
673
|
+
var root$2 = $.from_svg(`<g class="balance-chart"><!><!></g>`);
|
|
674
|
+
|
|
675
|
+
function DivergingBarChart($$anchor, $$props) {
|
|
676
|
+
$.push($$props, true);
|
|
677
|
+
|
|
678
|
+
const setdiff = (x, y) => {
|
|
679
|
+
let a = new Set(x);
|
|
680
|
+
let b = new Set(y);
|
|
681
|
+
|
|
682
|
+
return new Set([...a].filter((x) => !b.has(x)));
|
|
683
|
+
};
|
|
684
|
+
|
|
685
|
+
const union = (x, y) => {
|
|
686
|
+
let a = new Set(x);
|
|
687
|
+
let b = new Set(y);
|
|
688
|
+
|
|
689
|
+
return new Set([...a, ...b]);
|
|
690
|
+
};
|
|
691
|
+
|
|
692
|
+
let types_1 = $.derived(() => $$props.test_elem_1.map((d) => d.types));
|
|
693
|
+
let types_2 = $.derived(() => $$props.test_elem_2.map((d) => d.types));
|
|
694
|
+
let union_types = $.derived(() => union($.get(types_1), $.get(types_2)));
|
|
695
|
+
let tot_types = $.derived(() => $.get(types_1).length + $.get(types_2).length);
|
|
696
|
+
let width = 200;
|
|
697
|
+
let margin = { right: 40, top: 30, left: 40, bottom: 10 };
|
|
698
|
+
let yPadding = 0.5;
|
|
699
|
+
let colors = ["lightgrey", "lightblue"];
|
|
700
|
+
|
|
701
|
+
let dat = $.proxy([
|
|
702
|
+
{
|
|
703
|
+
y_coord: "total count",
|
|
704
|
+
frequency: +($.get(types_2).length / $.get(tot_types)).toFixed(3)
|
|
705
|
+
},
|
|
706
|
+
{
|
|
707
|
+
y_coord: "total count",
|
|
708
|
+
frequency: -($.get(types_1).length / $.get(tot_types)).toFixed(3)
|
|
709
|
+
},
|
|
710
|
+
{
|
|
711
|
+
y_coord: "all names",
|
|
712
|
+
frequency: +($.get(types_2).length / $.get(union_types).size).toFixed(3)
|
|
713
|
+
},
|
|
714
|
+
{
|
|
715
|
+
y_coord: "all names",
|
|
716
|
+
frequency: -($.get(types_1).length / $.get(union_types).size).toFixed(3)
|
|
717
|
+
},
|
|
718
|
+
{
|
|
719
|
+
y_coord: "exclusive names",
|
|
720
|
+
frequency: +(setdiff($.get(types_2), $.get(types_1)).size / $.get(types_2).length).toFixed(3)
|
|
721
|
+
},
|
|
722
|
+
{
|
|
723
|
+
y_coord: "exclusive names",
|
|
724
|
+
frequency: -(setdiff($.get(types_1), $.get(types_2)).size / $.get(types_1).length).toFixed(3)
|
|
725
|
+
}
|
|
726
|
+
]);
|
|
727
|
+
|
|
728
|
+
let X = $.derived(() => dat.map((d) => d.frequency));
|
|
729
|
+
let Y = $.derived(() => dat.map((d) => d.y_coord));
|
|
730
|
+
let xRange = $.derived(() => [margin.left, width - margin.right]);
|
|
731
|
+
let xDomain = $.derived(() => extent($.get(X)));
|
|
732
|
+
let yDomain = $.derived(() => new InternSet($.get(Y)));
|
|
733
|
+
let height = $.derived(() => Math.ceil(($.get(yDomain).size + yPadding) * 25) + margin.top + margin.bottom);
|
|
734
|
+
let I = $.derived(() => range($.get(X).length).filter((i) => $.get(yDomain).has($.get(Y)[i])));
|
|
735
|
+
$.derived(() => rollup($.get(I), ([i]) => $.get(X)[i], (i) => $.get(Y)[i]));
|
|
736
|
+
let xScale = $.derived(() => scaleLinear($.get(xDomain), $.get(xRange)));
|
|
737
|
+
let yScale = $.derived(() => scaleBand().domain($.get(yDomain)).range([margin.top, $.get(height) - margin.bottom]).padding(yPadding));
|
|
738
|
+
let format = $.derived(() => $.get(xScale).tickFormat(100, "%"));
|
|
739
|
+
var g = root$2();
|
|
740
|
+
var node = $.child(g);
|
|
741
|
+
|
|
742
|
+
$.each(node, 17, () => dat, $.index, ($$anchor, d, i) => {
|
|
743
|
+
var fragment = root_1$1();
|
|
744
|
+
var rect = $.first_child(fragment);
|
|
745
|
+
var text_1 = $.sibling(rect);
|
|
746
|
+
var text_2 = $.child(text_1, true);
|
|
747
|
+
|
|
748
|
+
$.reset(text_1);
|
|
749
|
+
|
|
750
|
+
$.template_effect(
|
|
751
|
+
($0, $1, $2, $3, $4, $5, $6) => {
|
|
752
|
+
$.set_attribute(rect, 'x', $0);
|
|
753
|
+
$.set_attribute(rect, 'y', $1);
|
|
754
|
+
$.set_attribute(rect, 'fill', colors[$.get(X)[i] > 0 ? colors.length - 1 : 0]);
|
|
755
|
+
$.set_attribute(rect, 'width', $2);
|
|
756
|
+
$.set_attribute(rect, 'height', $3);
|
|
757
|
+
$.set_attribute(text_1, 'x', $4);
|
|
758
|
+
$.set_attribute(text_1, 'y', $5);
|
|
759
|
+
$.set_attribute(text_1, 'text-anchor', $.get(d).frequency < 0 ? "end" : "start");
|
|
760
|
+
$.set_text(text_2, $6);
|
|
761
|
+
},
|
|
762
|
+
[
|
|
763
|
+
() => Math.min($.get(xScale)(0), $.get(xScale)($.get(d).frequency)),
|
|
764
|
+
() => $.get(yScale)($.get(d).y_coord),
|
|
765
|
+
() => Math.abs($.get(xScale)($.get(d).frequency) - $.get(xScale)(0)),
|
|
766
|
+
() => $.get(yScale).bandwidth(),
|
|
767
|
+
() => $.get(xScale)($.get(X)[i]) + Math.sign($.get(X)[i] - 0) * 4,
|
|
768
|
+
() => $.get(yScale)($.get(Y)[i]) + $.get(yScale).bandwidth() / 2,
|
|
769
|
+
() => $.get(format)(Math.abs($.get(d).frequency))
|
|
770
|
+
]
|
|
771
|
+
);
|
|
772
|
+
|
|
773
|
+
$.append($$anchor, fragment);
|
|
774
|
+
});
|
|
775
|
+
|
|
776
|
+
var node_1 = $.sibling(node);
|
|
777
|
+
|
|
778
|
+
$.each(node_1, 17, () => $.get(yScale).domain(), $.index, ($$anchor, text) => {
|
|
779
|
+
var g_1 = root_2$1();
|
|
780
|
+
var text_3 = $.child(g_1);
|
|
781
|
+
var text_4 = $.child(text_3, true);
|
|
782
|
+
|
|
783
|
+
$.reset(text_3);
|
|
784
|
+
$.reset(g_1);
|
|
785
|
+
|
|
786
|
+
$.template_effect(
|
|
787
|
+
($0, $1) => {
|
|
788
|
+
$.set_attribute(text_3, 'x', $0);
|
|
789
|
+
$.set_attribute(text_3, 'y', $1);
|
|
790
|
+
$.set_text(text_4, $.get(text));
|
|
791
|
+
},
|
|
792
|
+
[
|
|
793
|
+
() => $.get(xScale)(0),
|
|
794
|
+
() => $.get(yScale)($.get(text)) + $.get(yScale).bandwidth() / 2
|
|
795
|
+
]
|
|
796
|
+
);
|
|
797
|
+
|
|
798
|
+
$.append($$anchor, g_1);
|
|
799
|
+
});
|
|
800
|
+
|
|
801
|
+
$.reset(g);
|
|
802
|
+
$.template_effect(() => $.set_attribute(g, 'transform', `translate(${$$props.DiamondWidth - 75}, ${$$props.DiamondHeight + 75})`));
|
|
803
|
+
$.append($$anchor, g);
|
|
804
|
+
$.pop();
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
var root_1 = $.from_svg(`<rect stroke="whitesmoke" stroke-width="1"></rect>`);
|
|
808
|
+
var root_3 = $.from_svg(`<g class="legend-title"><text font-size="13">Counts per cell</text></g>`);
|
|
809
|
+
var root_2 = $.from_svg(`<g class="legend-text"><text font-size="10" dx="20"> </text></g><!>`, 1);
|
|
810
|
+
var root$1 = $.from_svg(`<g class="legend-container"></g><!>`, 1);
|
|
811
|
+
|
|
812
|
+
function Legend($$anchor, $$props) {
|
|
813
|
+
$.push($$props, true);
|
|
814
|
+
|
|
815
|
+
const N_CATEGO = 20;
|
|
816
|
+
const myramp = range(N_CATEGO).map((i) => rgb(interpolateInferno(i / (N_CATEGO - 1))).hex());
|
|
817
|
+
const color = scaleOrdinal(range(N_CATEGO), myramp);
|
|
818
|
+
let height = 370;
|
|
819
|
+
const margin = { right: 40, top: 65, left: 10 };
|
|
820
|
+
let innerHeight = $.derived(() => height - margin.top - margin.right);
|
|
821
|
+
let max_rank = $.derived(() => max($$props.diamond_dat, (d) => d.rank_L[1]));
|
|
822
|
+
let y = $.derived(() => scaleBand().domain(color.domain().reverse()).rangeRound([0, $.get(innerHeight)]));
|
|
823
|
+
|
|
824
|
+
let logY = $.derived(() => scaleLog().domain([
|
|
825
|
+
1,
|
|
826
|
+
10 ** Math.ceil(Math.max(Math.log10($.get(max_rank))) - 1)
|
|
827
|
+
]).rangeRound([0, $.get(innerHeight)]).nice());
|
|
828
|
+
|
|
829
|
+
let logFormat10 = $.derived(() => $.get(logY).tickFormat());
|
|
830
|
+
let yTicks = $.derived(() => $.get(logY).ticks());
|
|
831
|
+
var fragment = root$1();
|
|
832
|
+
var g = $.first_child(fragment);
|
|
833
|
+
|
|
834
|
+
$.each(g, 21, () => color.domain(), $.index, ($$anchor, d) => {
|
|
835
|
+
var rect = root_1();
|
|
836
|
+
|
|
837
|
+
$.set_attribute(rect, 'x', 0);
|
|
838
|
+
$.set_attribute(rect, 'width', 14);
|
|
839
|
+
$.set_attribute(rect, 'height', 13);
|
|
840
|
+
|
|
841
|
+
$.template_effect(
|
|
842
|
+
($0, $1) => {
|
|
843
|
+
$.set_attribute(rect, 'y', $0);
|
|
844
|
+
$.set_attribute(rect, 'fill', $1);
|
|
845
|
+
},
|
|
846
|
+
[
|
|
847
|
+
() => $.get(y)($.get(d)),
|
|
848
|
+
() => color($.get(d))
|
|
849
|
+
]
|
|
850
|
+
);
|
|
851
|
+
|
|
852
|
+
$.append($$anchor, rect);
|
|
853
|
+
});
|
|
854
|
+
|
|
855
|
+
$.reset(g);
|
|
856
|
+
|
|
857
|
+
var node = $.sibling(g);
|
|
858
|
+
|
|
859
|
+
$.each(node, 17, () => $.get(yTicks), $.index, ($$anchor, tick, i) => {
|
|
860
|
+
var fragment_1 = root_2();
|
|
861
|
+
var g_1 = $.first_child(fragment_1);
|
|
862
|
+
var text = $.child(g_1);
|
|
863
|
+
var text_1 = $.child(text, true);
|
|
864
|
+
|
|
865
|
+
$.reset(text);
|
|
866
|
+
$.reset(g_1);
|
|
867
|
+
|
|
868
|
+
var node_1 = $.sibling(g_1);
|
|
869
|
+
|
|
870
|
+
{
|
|
871
|
+
var consequent = ($$anchor) => {
|
|
872
|
+
var g_2 = root_3();
|
|
873
|
+
var text_2 = $.child(g_2);
|
|
874
|
+
|
|
875
|
+
$.set_attribute(text_2, 'dy', "9");
|
|
876
|
+
$.reset(g_2);
|
|
877
|
+
|
|
878
|
+
$.template_effect(($0) => $.set_attribute(g_2, 'transform', `translate(${margin.left}, ${$0 ?? ''})`), [
|
|
879
|
+
() => $$props.DiamondHeight + $.get(logY)($.get(tick)) - margin.top
|
|
880
|
+
]);
|
|
881
|
+
|
|
882
|
+
$.append($$anchor, g_2);
|
|
883
|
+
};
|
|
884
|
+
|
|
885
|
+
$.if(node_1, ($$render) => {
|
|
886
|
+
if (i === $.get(yTicks).length - 1) $$render(consequent);
|
|
887
|
+
});
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
$.template_effect(
|
|
891
|
+
($0, $1) => {
|
|
892
|
+
$.set_attribute(g_1, 'transform', `translate(${margin.left}, ${$0 ?? ''})`);
|
|
893
|
+
$.set_attribute(text, 'dy', $.get(yTicks).length - 1 == i ? "-3" : "13");
|
|
894
|
+
$.set_text(text_1, $1);
|
|
895
|
+
},
|
|
896
|
+
[
|
|
897
|
+
() => $$props.DiamondHeight + $.get(logY)($.get(tick)) - margin.top,
|
|
898
|
+
() => $.get(logFormat10)($.get(tick))
|
|
899
|
+
]
|
|
900
|
+
);
|
|
901
|
+
|
|
902
|
+
$.append($$anchor, fragment_1);
|
|
903
|
+
});
|
|
904
|
+
|
|
905
|
+
$.template_effect(() => $.set_attribute(g, 'transform', `translate(${margin.left}, ${$$props.DiamondHeight - margin.top})`));
|
|
906
|
+
$.append($$anchor, fragment);
|
|
907
|
+
$.pop();
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
var root = $.from_html(`<div><svg id="allotaxonometer-svg" class="svelte-n6o6ey"><!><!><!><!></svg></div>`);
|
|
911
|
+
|
|
912
|
+
function Dashboard($$anchor, $$props) {
|
|
913
|
+
let diamond_count = $.prop($$props, 'diamond_count', 19, () => []),
|
|
914
|
+
diamond_dat = $.prop($$props, 'diamond_dat', 19, () => []),
|
|
915
|
+
barData = $.prop($$props, 'barData', 19, () => []),
|
|
916
|
+
test_elem_1 = $.prop($$props, 'test_elem_1', 3, null),
|
|
917
|
+
test_elem_2 = $.prop($$props, 'test_elem_2', 3, null),
|
|
918
|
+
height = $.prop($$props, 'height', 3, 815),
|
|
919
|
+
width = $.prop($$props, 'width', 3, 1200),
|
|
920
|
+
DiamondHeight = $.prop($$props, 'DiamondHeight', 3, 600),
|
|
921
|
+
DiamondWidth = $.prop($$props, 'DiamondWidth', 3, 600),
|
|
922
|
+
DiamondInnerHeight = $.prop($$props, 'DiamondInnerHeight', 3, 440),
|
|
923
|
+
margin = $.prop($$props, 'margin', 19, () => ({ inner: 160, diamond: 40 })),
|
|
924
|
+
trueDiamondHeight = $.prop($$props, 'trueDiamondHeight', 3, 400),
|
|
925
|
+
alpha = $.prop($$props, 'alpha', 3, 0.58),
|
|
926
|
+
maxlog10 = $.prop($$props, 'maxlog10', 3, 0),
|
|
927
|
+
rtd = $.prop($$props, 'rtd', 3, null),
|
|
928
|
+
title = $.prop($$props, 'title', 19, () => ['System 1', 'System 2']),
|
|
929
|
+
className = $.prop($$props, 'class', 3, ''),
|
|
930
|
+
style = $.prop($$props, 'style', 3, ''),
|
|
931
|
+
showDiamond = $.prop($$props, 'showDiamond', 3, true),
|
|
932
|
+
showWordshift = $.prop($$props, 'showWordshift', 3, true),
|
|
933
|
+
showDivergingBar = $.prop($$props, 'showDivergingBar', 3, true),
|
|
934
|
+
showLegend = $.prop($$props, 'showLegend', 3, true),
|
|
935
|
+
restProps = $.rest_props($$props, [
|
|
936
|
+
'$$slots',
|
|
937
|
+
'$$events',
|
|
938
|
+
'$$legacy',
|
|
939
|
+
'diamond_count',
|
|
940
|
+
'diamond_dat',
|
|
941
|
+
'barData',
|
|
942
|
+
'test_elem_1',
|
|
943
|
+
'test_elem_2',
|
|
944
|
+
'height',
|
|
945
|
+
'width',
|
|
946
|
+
'DiamondHeight',
|
|
947
|
+
'DiamondWidth',
|
|
948
|
+
'DiamondInnerHeight',
|
|
949
|
+
'margin',
|
|
950
|
+
'trueDiamondHeight',
|
|
951
|
+
'alpha',
|
|
952
|
+
'maxlog10',
|
|
953
|
+
'rtd',
|
|
954
|
+
'title',
|
|
955
|
+
'class',
|
|
956
|
+
'style',
|
|
957
|
+
'showDiamond',
|
|
958
|
+
'showWordshift',
|
|
959
|
+
'showDivergingBar',
|
|
960
|
+
'showLegend'
|
|
961
|
+
]);
|
|
962
|
+
|
|
963
|
+
var div = root();
|
|
964
|
+
|
|
965
|
+
$.attribute_effect(
|
|
966
|
+
div,
|
|
967
|
+
() => ({
|
|
968
|
+
class: `allotaxonometer-dashboard ${className() ?? ''}`,
|
|
969
|
+
style: style(),
|
|
970
|
+
...restProps
|
|
971
|
+
}),
|
|
972
|
+
undefined,
|
|
973
|
+
'svelte-n6o6ey'
|
|
974
|
+
);
|
|
975
|
+
|
|
976
|
+
var svg = $.child(div);
|
|
977
|
+
var node = $.child(svg);
|
|
978
|
+
|
|
979
|
+
{
|
|
980
|
+
var consequent = ($$anchor) => {
|
|
981
|
+
Diamond($$anchor, {
|
|
982
|
+
get diamond_count() {
|
|
983
|
+
return diamond_count();
|
|
984
|
+
},
|
|
985
|
+
get diamond_dat() {
|
|
986
|
+
return diamond_dat();
|
|
987
|
+
},
|
|
988
|
+
get DiamondInnerHeight() {
|
|
989
|
+
return DiamondInnerHeight();
|
|
990
|
+
},
|
|
991
|
+
get margin() {
|
|
992
|
+
return margin();
|
|
993
|
+
},
|
|
994
|
+
get trueDiamondHeight() {
|
|
995
|
+
return trueDiamondHeight();
|
|
996
|
+
},
|
|
997
|
+
get alpha() {
|
|
998
|
+
return alpha();
|
|
999
|
+
},
|
|
1000
|
+
get maxlog10() {
|
|
1001
|
+
return maxlog10();
|
|
1002
|
+
},
|
|
1003
|
+
get rtd() {
|
|
1004
|
+
return rtd();
|
|
1005
|
+
},
|
|
1006
|
+
get title() {
|
|
1007
|
+
return title();
|
|
1008
|
+
}
|
|
1009
|
+
});
|
|
1010
|
+
};
|
|
1011
|
+
|
|
1012
|
+
$.if(node, ($$render) => {
|
|
1013
|
+
if (showDiamond()) $$render(consequent);
|
|
1014
|
+
});
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1017
|
+
var node_1 = $.sibling(node);
|
|
1018
|
+
|
|
1019
|
+
{
|
|
1020
|
+
var consequent_1 = ($$anchor) => {
|
|
1021
|
+
Wordshift($$anchor, {
|
|
1022
|
+
get barData() {
|
|
1023
|
+
return barData();
|
|
1024
|
+
},
|
|
1025
|
+
get DashboardHeight() {
|
|
1026
|
+
return height();
|
|
1027
|
+
},
|
|
1028
|
+
get DashboardWidth() {
|
|
1029
|
+
return width();
|
|
1030
|
+
}
|
|
1031
|
+
});
|
|
1032
|
+
};
|
|
1033
|
+
|
|
1034
|
+
$.if(node_1, ($$render) => {
|
|
1035
|
+
if (showWordshift()) $$render(consequent_1);
|
|
1036
|
+
});
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
var node_2 = $.sibling(node_1);
|
|
1040
|
+
|
|
1041
|
+
{
|
|
1042
|
+
var consequent_2 = ($$anchor) => {
|
|
1043
|
+
DivergingBarChart($$anchor, {
|
|
1044
|
+
get test_elem_1() {
|
|
1045
|
+
return test_elem_1();
|
|
1046
|
+
},
|
|
1047
|
+
get test_elem_2() {
|
|
1048
|
+
return test_elem_2();
|
|
1049
|
+
},
|
|
1050
|
+
get DiamondHeight() {
|
|
1051
|
+
return DiamondHeight();
|
|
1052
|
+
},
|
|
1053
|
+
get DiamondWidth() {
|
|
1054
|
+
return DiamondWidth();
|
|
1055
|
+
}
|
|
1056
|
+
});
|
|
1057
|
+
};
|
|
1058
|
+
|
|
1059
|
+
$.if(node_2, ($$render) => {
|
|
1060
|
+
if (showDivergingBar()) $$render(consequent_2);
|
|
1061
|
+
});
|
|
1062
|
+
}
|
|
1063
|
+
|
|
1064
|
+
var node_3 = $.sibling(node_2);
|
|
1065
|
+
|
|
1066
|
+
{
|
|
1067
|
+
var consequent_3 = ($$anchor) => {
|
|
1068
|
+
Legend($$anchor, {
|
|
1069
|
+
get diamond_dat() {
|
|
1070
|
+
return diamond_dat();
|
|
1071
|
+
},
|
|
1072
|
+
get DiamondHeight() {
|
|
1073
|
+
return DiamondHeight();
|
|
1074
|
+
}
|
|
1075
|
+
});
|
|
1076
|
+
};
|
|
1077
|
+
|
|
1078
|
+
$.if(node_3, ($$render) => {
|
|
1079
|
+
if (showLegend()) $$render(consequent_3);
|
|
1080
|
+
});
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1083
|
+
$.reset(svg);
|
|
1084
|
+
$.reset(div);
|
|
1085
|
+
|
|
1086
|
+
$.template_effect(() => {
|
|
1087
|
+
$.set_attribute(svg, 'height', height());
|
|
1088
|
+
$.set_attribute(svg, 'width', width());
|
|
1089
|
+
});
|
|
1090
|
+
|
|
1091
|
+
$.append($$anchor, div);
|
|
1092
|
+
}
|
|
1093
|
+
|
|
1094
|
+
export { Dashboard, Diamond, DivergingBarChart, Legend, Wordshift };
|
package/dist/style.css
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
|
|
2
|
+
.xlab.svelte-1y8xk6i {
|
|
3
|
+
text-anchor: middle;
|
|
4
|
+
font-size: 14px;
|
|
5
|
+
fill: rgb(0, 0, 0);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.ylab.svelte-1y8visx {
|
|
9
|
+
text-anchor: middle;
|
|
10
|
+
font-size: 14px;
|
|
11
|
+
fill: rgb(0, 0, 0);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.barChart-container.svelte-37sv8o {
|
|
15
|
+
position: relative;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.allotaxonometer-dashboard.svelte-n6o6ey {
|
|
19
|
+
/* Minimal base styles - users can override */
|
|
20
|
+
display: block;
|
|
21
|
+
width: 100%;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
svg.svelte-n6o6ey {
|
|
25
|
+
display: block;
|
|
26
|
+
width: 100%;
|
|
27
|
+
height: auto;
|
|
28
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "allotaxonometer-ui",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Headless UI components for allotaxonometer visualizations",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": ["dist", "README.md"],
|
|
16
|
+
"keywords": ["svelte", "visualization", "allotaxonometer", "dashboard"],
|
|
17
|
+
"author": "Your Name <your.email@example.com>",
|
|
18
|
+
"license": "MIT",
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "https://github.com/yourusername/allotaxonometer-ui.git"
|
|
22
|
+
},
|
|
23
|
+
"homepage": "https://github.com/yourusername/allotaxonometer-ui#readme",
|
|
24
|
+
"peerDependencies": {
|
|
25
|
+
"svelte": "^5.0.0"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@sveltejs/vite-plugin-svelte": "^4.0.0",
|
|
29
|
+
"svelte": "^5.0.0",
|
|
30
|
+
"typescript": "^5.0.0",
|
|
31
|
+
"vite": "^5.0.3"
|
|
32
|
+
},
|
|
33
|
+
"scripts": {
|
|
34
|
+
"dev": "vite",
|
|
35
|
+
"build": "vite build",
|
|
36
|
+
"prepublishOnly": "npm run build"
|
|
37
|
+
}
|
|
38
|
+
}
|