allotaxonometer-ui 0.1.1 → 0.1.3
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/index.js +1762 -479
- package/dist/ssr/index.js +449 -205
- package/dist/style.css +2 -2
- package/package.json +15 -6
package/dist/index.js
CHANGED
|
@@ -1,505 +1,1788 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
1
|
+
import 'svelte/internal/disclose-version';
|
|
2
|
+
import * as $ from 'svelte/internal/client';
|
|
3
|
+
import * as d3 from 'd3';
|
|
4
|
+
import { map, extent, InternSet, range, rollup, scaleLinear, scaleBand, rgb, interpolateInferno, scaleOrdinal, max, scaleLog } from 'd3';
|
|
5
|
+
import { descending, sum, group, extent as extent$1 } from 'd3-array';
|
|
6
|
+
|
|
7
|
+
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);
|
|
8
|
+
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>`);
|
|
9
|
+
|
|
10
|
+
function AxisX($$anchor, $$props) {
|
|
11
|
+
$.push($$props, true);
|
|
12
|
+
|
|
13
|
+
let logFormat10 = $$props.scale.tickFormat();
|
|
14
|
+
let xTicks = $$props.scale.ticks();
|
|
15
|
+
var g = root$8();
|
|
16
|
+
var node = $.child(g);
|
|
17
|
+
|
|
18
|
+
$.each(node, 17, () => xTicks, $.index, ($$anchor, tick) => {
|
|
19
|
+
var fragment = root_1$7();
|
|
20
|
+
var g_1 = $.first_child(fragment);
|
|
21
|
+
var g_2 = $.sibling(g_1);
|
|
22
|
+
var text = $.child(g_2);
|
|
23
|
+
var text_1 = $.child(text, true);
|
|
24
|
+
|
|
25
|
+
$.reset(text);
|
|
26
|
+
$.reset(g_2);
|
|
27
|
+
|
|
28
|
+
$.template_effect(
|
|
29
|
+
($0, $1, $2) => {
|
|
30
|
+
$.set_attribute(g_1, 'transform', `translate(${$0 ?? ''}, 0)`);
|
|
31
|
+
$.set_attribute(g_2, 'transform', `translate(${$1 ?? ''}, 0) scale(-1,1) rotate(45)`);
|
|
32
|
+
$.set_text(text_1, $2);
|
|
33
|
+
},
|
|
34
|
+
[
|
|
35
|
+
() => $$props.scale($.get(tick)),
|
|
36
|
+
() => $$props.scale($.get(tick)),
|
|
37
|
+
() => logFormat10($.get(tick))
|
|
38
|
+
]
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
$.append($$anchor, fragment);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
var g_3 = $.sibling(node);
|
|
45
|
+
var text_2 = $.child(g_3);
|
|
46
|
+
var text_3 = $.sibling(text_2);
|
|
47
|
+
var text_4 = $.sibling(text_3);
|
|
48
|
+
var text_5 = $.child(text_4, true);
|
|
49
|
+
|
|
50
|
+
$.reset(text_4);
|
|
51
|
+
|
|
52
|
+
var text_6 = $.sibling(text_4);
|
|
53
|
+
var text_7 = $.sibling(text_6);
|
|
54
|
+
var text_8 = $.sibling(text_7);
|
|
55
|
+
|
|
56
|
+
$.set_attribute(text_8, 'x', 40);
|
|
57
|
+
|
|
58
|
+
var text_9 = $.sibling(text_8);
|
|
59
|
+
|
|
60
|
+
$.set_attribute(text_9, 'x', 40);
|
|
61
|
+
$.reset(g_3);
|
|
62
|
+
$.reset(g);
|
|
63
|
+
|
|
64
|
+
$.template_effect(() => {
|
|
65
|
+
$.set_attribute(g, 'transform', `translate(0, ${$$props.height ?? ''})`);
|
|
66
|
+
$.set_attribute(g_3, 'transform', `scale(-1,1) translate(-${$$props.height ?? ''}, 0)`);
|
|
67
|
+
$.set_attribute(text_2, 'x', $$props.height / 2);
|
|
68
|
+
$.set_attribute(text_3, 'x', $$props.height / 2);
|
|
69
|
+
$.set_attribute(text_4, 'x', $$props.height / 2);
|
|
70
|
+
$.set_text(text_5, $$props.title[1]);
|
|
71
|
+
$.set_attribute(text_6, 'x', $$props.height - 40);
|
|
72
|
+
$.set_attribute(text_7, 'x', $$props.height - 40);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
$.append($$anchor, g);
|
|
76
|
+
$.pop();
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
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);
|
|
80
|
+
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>`);
|
|
81
|
+
|
|
82
|
+
function AxisY($$anchor, $$props) {
|
|
83
|
+
$.push($$props, true);
|
|
84
|
+
|
|
85
|
+
let logFormat10 = $$props.scale.tickFormat();
|
|
86
|
+
let yTicks = $.derived(() => $$props.scale.ticks());
|
|
87
|
+
var g = root$7();
|
|
88
|
+
var node = $.child(g);
|
|
89
|
+
|
|
90
|
+
$.each(node, 17, () => $.get(yTicks), $.index, ($$anchor, tick) => {
|
|
91
|
+
var fragment = root_1$6();
|
|
92
|
+
var g_1 = $.first_child(fragment);
|
|
93
|
+
var g_2 = $.sibling(g_1);
|
|
94
|
+
var text = $.child(g_2);
|
|
95
|
+
var text_1 = $.child(text, true);
|
|
96
|
+
|
|
97
|
+
$.reset(text);
|
|
98
|
+
$.reset(g_2);
|
|
99
|
+
|
|
100
|
+
$.template_effect(
|
|
101
|
+
($0, $1, $2) => {
|
|
102
|
+
$.set_attribute(g_1, 'transform', `translate(0, ${$0 ?? ''})`);
|
|
103
|
+
$.set_attribute(g_2, 'transform', `translate(0, ${$1 ?? ''}) rotate(45)`);
|
|
104
|
+
$.set_text(text_1, $2);
|
|
105
|
+
},
|
|
106
|
+
[
|
|
107
|
+
() => $$props.scale($.get(tick)),
|
|
108
|
+
() => $$props.scale($.get(tick)),
|
|
109
|
+
() => logFormat10($.get(tick))
|
|
110
|
+
]
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
$.append($$anchor, fragment);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
var g_3 = $.sibling(node);
|
|
117
|
+
var text_2 = $.child(g_3);
|
|
118
|
+
var text_3 = $.sibling(text_2);
|
|
119
|
+
var text_4 = $.sibling(text_3);
|
|
120
|
+
var text_5 = $.child(text_4, true);
|
|
121
|
+
|
|
122
|
+
$.reset(text_4);
|
|
123
|
+
|
|
124
|
+
var text_6 = $.sibling(text_4);
|
|
125
|
+
var text_7 = $.sibling(text_6);
|
|
126
|
+
var text_8 = $.sibling(text_7);
|
|
127
|
+
|
|
128
|
+
$.set_attribute(text_8, 'x', 40);
|
|
129
|
+
|
|
130
|
+
var text_9 = $.sibling(text_8);
|
|
131
|
+
|
|
132
|
+
$.set_attribute(text_9, 'x', 40);
|
|
133
|
+
$.reset(g_3);
|
|
134
|
+
$.reset(g);
|
|
135
|
+
|
|
136
|
+
$.template_effect(() => {
|
|
137
|
+
$.set_attribute(g, 'transform', `translate(${$$props.height ?? ''}, 0) scale(-1, 1)`);
|
|
138
|
+
$.set_attribute(text_2, 'x', $$props.height / 2);
|
|
139
|
+
$.set_attribute(text_3, 'x', $$props.height / 2);
|
|
140
|
+
$.set_attribute(text_4, 'x', $$props.height / 2);
|
|
141
|
+
$.set_text(text_5, $$props.title[0]);
|
|
142
|
+
$.set_attribute(text_6, 'x', $$props.height - 40);
|
|
143
|
+
$.set_attribute(text_7, 'x', $$props.height - 40);
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
$.append($$anchor, g);
|
|
147
|
+
$.pop();
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
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);
|
|
151
|
+
var root$6 = $.from_svg(`<g class="grid"></g>`);
|
|
152
|
+
|
|
153
|
+
function Grid($$anchor, $$props) {
|
|
154
|
+
$.push($$props, true);
|
|
155
|
+
|
|
156
|
+
let xygridLines = $.derived(() => $$props.scale.ticks($$props.ncells / 2));
|
|
157
|
+
var g = root$6();
|
|
158
|
+
|
|
159
|
+
$.each(g, 21, () => $.get(xygridLines), $.index, ($$anchor, yline, index) => {
|
|
160
|
+
var fragment = root_1$5();
|
|
161
|
+
var g_1 = $.first_child(fragment);
|
|
162
|
+
var line = $.child(g_1);
|
|
163
|
+
|
|
164
|
+
$.set_attribute(line, 'opacity', index === 0 ? 0 : 1);
|
|
165
|
+
$.reset(g_1);
|
|
166
|
+
|
|
167
|
+
var g_2 = $.sibling(g_1);
|
|
168
|
+
var line_1 = $.child(g_2);
|
|
169
|
+
|
|
170
|
+
$.set_attribute(line_1, 'opacity', index === 0 ? 0 : 1);
|
|
171
|
+
$.reset(g_2);
|
|
172
|
+
|
|
173
|
+
$.template_effect(
|
|
174
|
+
($0, $1) => {
|
|
175
|
+
$.set_attribute(g_1, 'transform', `translate(${$0 ?? ''}, 0)`);
|
|
176
|
+
$.set_attribute(line, 'y1', $$props.height);
|
|
177
|
+
$.set_attribute(g_2, 'transform', `translate(0, ${$1 ?? ''})`);
|
|
178
|
+
$.set_attribute(line_1, 'x1', $$props.height);
|
|
179
|
+
},
|
|
180
|
+
[
|
|
181
|
+
() => $$props.wxy($.get(yline)),
|
|
182
|
+
() => $$props.wxy($.get(yline))
|
|
183
|
+
]
|
|
184
|
+
);
|
|
185
|
+
|
|
186
|
+
$.append($$anchor, fragment);
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
$.reset(g);
|
|
190
|
+
$.append($$anchor, g);
|
|
191
|
+
$.pop();
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
var root_1$4 = $.from_svg(`<path fill="none" stroke="grey" stroke-width="0.9" stroke-opacity="0.9"></path>`);
|
|
195
|
+
var root$5 = $.from_svg(`<g class="contours"></g>`);
|
|
196
|
+
|
|
197
|
+
function Contours($$anchor, $$props) {
|
|
198
|
+
$.push($$props, true);
|
|
199
|
+
|
|
200
|
+
function alpha_norm_type2(x1, x2, alpha) {
|
|
201
|
+
if (alpha == 0) {
|
|
202
|
+
return Math.abs(Math.log(x1 / x2));
|
|
203
|
+
} else if (alpha === Infinity) {
|
|
204
|
+
return x1 === x2 ? 0 : Math.max(x1, x2);
|
|
205
|
+
} else {
|
|
206
|
+
const prefactor = (alpha + 1) / alpha;
|
|
207
|
+
const power = 1 / (alpha + 1);
|
|
208
|
+
|
|
209
|
+
return prefactor * Math.abs(Math.pow(x1, alpha) - Math.pow(x2, alpha)) ** power;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
function make_grid(Ninset, tmpr1, tmpr2, alpha, divnorm) {
|
|
214
|
+
const deltamatrix = Array.from({ length: Ninset }, () => Array(Ninset).fill(0));
|
|
215
|
+
|
|
216
|
+
for (let i = 0; i < Ninset; i++) {
|
|
217
|
+
for (let j = 0; j < Ninset; j++) {
|
|
218
|
+
const divElem = alpha_norm_type2(1 / tmpr1[i], 1 / tmpr2[j], alpha);
|
|
219
|
+
|
|
220
|
+
deltamatrix[i][j] = divElem / divnorm;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
deltamatrix[i][i] = -1;
|
|
224
|
+
|
|
225
|
+
if (i < Ninset - 1) {
|
|
226
|
+
deltamatrix[i][i + 1] = -1;
|
|
227
|
+
deltamatrix[i + 1][i] = -1;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
return deltamatrix;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
function filter_contours(tmpcontours, Ninset, maxlog10) {
|
|
235
|
+
const chart2val = d3.scaleLinear().domain([0, Ninset]).range([0, maxlog10]);
|
|
236
|
+
let out = [];
|
|
237
|
+
|
|
238
|
+
tmpcontours.forEach((contour) => {
|
|
239
|
+
contour.coordinates.forEach((pair, i) => {
|
|
240
|
+
const tmpr1 = pair[0].map((d) => d[0]);
|
|
241
|
+
const tmpr2 = pair[0].map((d) => d[1]);
|
|
242
|
+
const filteredPairs = [];
|
|
243
|
+
|
|
244
|
+
for (let index = 0; index < tmpr1.length - 1; index++) {
|
|
245
|
+
const x1 = chart2val(tmpr1[index]);
|
|
246
|
+
const x2 = chart2val(tmpr2[index]);
|
|
247
|
+
const tmpxrot = Math.abs(x2 - x1) / Math.sqrt(2);
|
|
248
|
+
|
|
249
|
+
if (Math.abs(tmpxrot) >= 0.1 & x1 != maxlog10 & x2 != 0 & x1 != 0 & x2 != maxlog10) {
|
|
250
|
+
filteredPairs.push([x1, x2]);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
if (filteredPairs.length > 0) {
|
|
255
|
+
out.push(filteredPairs);
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
return out;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
function get_contours(alpha, maxlog10, divnorm) {
|
|
264
|
+
const Ninset = 10 ** 3;
|
|
265
|
+
const tmpr1 = d3.range(0, 1000).map((d) => Math.pow(10, d / 999 * 5));
|
|
266
|
+
const tmpr2 = d3.range(0, 1000).map((d) => Math.pow(10, d / 999 * 5));
|
|
267
|
+
const Ncontours = 10;
|
|
268
|
+
const scale = d3.scaleLinear().domain([0, Ncontours + 1]).range([1, tmpr1.length]);
|
|
269
|
+
const contour_indices = d3.range(Ncontours + 2).map((i) => Math.round(scale(i)));
|
|
270
|
+
const grid = make_grid(Ninset, tmpr1, tmpr2, alpha, divnorm);
|
|
271
|
+
const indices = contour_indices.slice(1, -1);
|
|
272
|
+
const lastRow = grid[grid.length - 1];
|
|
273
|
+
const heights = indices.map((index) => lastRow[index]);
|
|
274
|
+
const logTmpr = tmpr1.map(Math.log10);
|
|
275
|
+
const contourGenerator = d3.contours().size([logTmpr.length, logTmpr.length]).thresholds(heights);
|
|
276
|
+
const flatDeltamatrix = grid.flat();
|
|
277
|
+
const tmpcontours = contourGenerator(flatDeltamatrix);
|
|
278
|
+
|
|
279
|
+
return filter_contours(tmpcontours, Ninset, maxlog10);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// Only calculate contours in browser
|
|
283
|
+
let mycontours = $.derived(() => get_contours($$props.alpha, $$props.maxlog10, $$props.divnorm));
|
|
284
|
+
const x = $.derived(() => d3.scaleLinear([0, $$props.maxlog10], [0, $$props.DiamondInnerHeight]));
|
|
285
|
+
const y = $.derived(() => d3.scaleLinear([$$props.maxlog10, 0], [$$props.DiamondInnerHeight, 0]));
|
|
286
|
+
const pathData = d3.line().x((d, i) => $.get(x)(d[0])).y((d, i) => $.get(y)(d[1]));
|
|
287
|
+
var g = root$5();
|
|
288
|
+
|
|
289
|
+
$.each(g, 21, () => $.get(mycontours), $.index, ($$anchor, contour) => {
|
|
290
|
+
var path = root_1$4();
|
|
291
|
+
|
|
292
|
+
$.template_effect(($0) => $.set_attribute(path, 'd', $0), [() => pathData($.get(contour))]);
|
|
293
|
+
$.append($$anchor, path);
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
$.reset(g);
|
|
297
|
+
$.append($$anchor, g);
|
|
298
|
+
$.pop();
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
var root_1$3 = $.from_svg(`<rect stroke="black"></rect>`);
|
|
302
|
+
var root_2$3 = $.from_svg(`<g class="diamond-lab"><text dy="20" font-size="10"> </text></g>`);
|
|
303
|
+
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>`);
|
|
304
|
+
|
|
305
|
+
function Diamond($$anchor, $$props) {
|
|
306
|
+
$.push($$props, true);
|
|
307
|
+
|
|
308
|
+
let DiamondHeight = $.prop($$props, 'DiamondHeight', 3, 600),
|
|
309
|
+
marginInner = $.prop($$props, 'marginInner', 3, 160),
|
|
310
|
+
marginDiamond = $.prop($$props, 'marginDiamond', 3, 40);
|
|
311
|
+
|
|
312
|
+
// Extract data from dat object
|
|
313
|
+
let diamond_dat = $.derived(() => $$props.dat.counts);
|
|
314
|
+
$.derived(() => $$props.dat.deltas);
|
|
315
|
+
// Calculate derived dimensions (matching D3 version)
|
|
316
|
+
let innerHeight = $.derived(() => DiamondHeight() - marginInner());
|
|
317
|
+
let diamondHeight = $.derived(() => $.get(innerHeight) - marginDiamond());
|
|
318
|
+
|
|
319
|
+
function get_relevant_types(diamond_dat) {
|
|
320
|
+
// Use the logic from your D3 version instead
|
|
321
|
+
const ncells = d3.max(diamond_dat, (d) => d.x1);
|
|
322
|
+
const cumbin = d3.range(0, ncells, 1.5);
|
|
323
|
+
const relevant_types = [];
|
|
324
|
+
|
|
325
|
+
for (let sys of ["right", "left"]) {
|
|
326
|
+
for (let i = 1; i < cumbin.length; i++) {
|
|
327
|
+
const filtered_dat = diamond_dat.filter((d) => d.value > 0 && d.which_sys == sys).filter((d) => d.coord_on_diag >= cumbin[i - 1] && d.coord_on_diag < cumbin[i]);
|
|
328
|
+
|
|
329
|
+
if (filtered_dat.length > 0) {
|
|
330
|
+
const cos_dists = filtered_dat.map((d) => d.cos_dist);
|
|
331
|
+
const max_dist = cos_dists.reduce((a, b) => Math.max(a, b));
|
|
332
|
+
const max_dist_idx = cos_dists.indexOf(max_dist);
|
|
333
|
+
// SSR-safe random selection
|
|
334
|
+
const types = filtered_dat[max_dist_idx]['types'].split(",");
|
|
335
|
+
const name = types[Math.floor(Math.random() * types.length)];
|
|
336
|
+
|
|
337
|
+
relevant_types.push(name);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
return relevant_types;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
function rin(arr1, arr2) {
|
|
346
|
+
return Array.from(arr1, (x) => arr2.indexOf(x) !== -1);
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
// Wrangling data - Fixed variable references
|
|
350
|
+
let relevant_types = $.derived(() => get_relevant_types($.get(diamond_dat)));
|
|
351
|
+
let ncells = $.derived(() => d3.max($.get(diamond_dat), (d) => d.x1));
|
|
352
|
+
let max_rank = $.derived(() => d3.max($.get(diamond_dat), (d) => d.rank_L[1]));
|
|
353
|
+
let rounded_max_rank = $.derived(() => 10 ** Math.ceil(Math.log10($.get(max_rank))));
|
|
354
|
+
let xyDomain = $.derived(() => [1, $.get(rounded_max_rank)]);
|
|
355
|
+
// Scales (matching D3 version dimensions)
|
|
356
|
+
let xy = $.derived(() => d3.scaleBand().domain($.get(diamond_dat).map((d) => d.y1)).range([0, $.get(diamondHeight)]));
|
|
357
|
+
let logScale = $.derived(() => d3.scaleLog().domain($.get(xyDomain)).range([0, $.get(innerHeight)]).nice());
|
|
358
|
+
let linScale = $.derived(() => d3.scaleLinear().domain([0, $.get(ncells) - 1]).range([0, $.get(innerHeight)]));
|
|
359
|
+
let wxy = $.derived(() => d3.scaleBand().domain(d3.range($.get(ncells))).range([0, $.get(innerHeight)]));
|
|
360
|
+
let color_scale = d3.scaleSequentialLog().domain([$.get(rounded_max_rank), 1]).interpolator(d3.interpolateInferno);
|
|
361
|
+
|
|
362
|
+
// Background triangles (using innerHeight like D3 version)
|
|
363
|
+
let blue_triangle = $.derived(() => [
|
|
364
|
+
[
|
|
365
|
+
$.get(innerHeight),
|
|
366
|
+
$.get(innerHeight)
|
|
367
|
+
],
|
|
368
|
+
[0, 0],
|
|
369
|
+
[0, $.get(innerHeight)]
|
|
370
|
+
].join(" "));
|
|
371
|
+
|
|
372
|
+
let grey_triangle = $.derived(() => [
|
|
373
|
+
[
|
|
374
|
+
$.get(innerHeight),
|
|
375
|
+
$.get(innerHeight)
|
|
376
|
+
],
|
|
377
|
+
[0, 0],
|
|
378
|
+
[$.get(innerHeight), 0]
|
|
379
|
+
].join(" "));
|
|
380
|
+
|
|
381
|
+
function filter_labs(d, relevant_types) {
|
|
382
|
+
return rin(relevant_types, d.types.split(",")).some((x) => x === true);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
var g = root$4();
|
|
386
|
+
var polygon = $.child(g);
|
|
387
|
+
var polygon_1 = $.sibling(polygon);
|
|
388
|
+
var node = $.sibling(polygon_1);
|
|
389
|
+
|
|
390
|
+
AxisX(node, {
|
|
391
|
+
get height() {
|
|
392
|
+
return $.get(innerHeight);
|
|
393
|
+
},
|
|
394
|
+
get scale() {
|
|
395
|
+
return $.get(logScale);
|
|
396
|
+
},
|
|
397
|
+
get title() {
|
|
398
|
+
return $$props.title;
|
|
399
|
+
}
|
|
400
|
+
});
|
|
401
|
+
|
|
402
|
+
var node_1 = $.sibling(node);
|
|
403
|
+
|
|
404
|
+
AxisY(node_1, {
|
|
405
|
+
get height() {
|
|
406
|
+
return $.get(innerHeight);
|
|
407
|
+
},
|
|
408
|
+
get scale() {
|
|
409
|
+
return $.get(logScale);
|
|
410
|
+
},
|
|
411
|
+
get title() {
|
|
412
|
+
return $$props.title;
|
|
413
|
+
}
|
|
414
|
+
});
|
|
415
|
+
|
|
416
|
+
var node_2 = $.sibling(node_1);
|
|
417
|
+
|
|
418
|
+
Grid(node_2, {
|
|
419
|
+
get height() {
|
|
420
|
+
return $.get(innerHeight);
|
|
421
|
+
},
|
|
422
|
+
get wxy() {
|
|
423
|
+
return $.get(wxy);
|
|
424
|
+
},
|
|
425
|
+
get ncells() {
|
|
426
|
+
return $.get(ncells);
|
|
427
|
+
},
|
|
428
|
+
get scale() {
|
|
429
|
+
return $.get(linScale);
|
|
430
|
+
}
|
|
431
|
+
});
|
|
432
|
+
|
|
433
|
+
var node_3 = $.sibling(node_2);
|
|
434
|
+
|
|
435
|
+
$.each(node_3, 17, () => $.get(diamond_dat), $.index, ($$anchor, d) => {
|
|
436
|
+
var rect = root_1$3();
|
|
437
|
+
|
|
438
|
+
$.template_effect(
|
|
439
|
+
($0, $1, $2, $3, $4) => {
|
|
440
|
+
$.set_attribute(rect, 'x', $0);
|
|
441
|
+
$.set_attribute(rect, 'y', $1);
|
|
442
|
+
$.set_attribute(rect, 'width', $2);
|
|
443
|
+
$.set_attribute(rect, 'height', $3);
|
|
444
|
+
$.set_attribute(rect, 'fill', $4);
|
|
445
|
+
$.set_attribute(rect, 'opacity', $.get(d).value === 0 ? 0 : 1);
|
|
446
|
+
$.set_attribute(rect, 'stroke-width', $.get(d).value === 0 ? 0 : 0.1);
|
|
447
|
+
$.set_attribute(rect, 'stroke-opacity', $.get(d).value === 0 ? 0 : 0.9);
|
|
448
|
+
},
|
|
449
|
+
[
|
|
450
|
+
() => $.get(xy)($.get(d).x1),
|
|
451
|
+
() => $.get(xy)($.get(d).y1),
|
|
452
|
+
() => $.get(xy).bandwidth(),
|
|
453
|
+
() => $.get(xy).bandwidth(),
|
|
454
|
+
() => color_scale($.get(d).value)
|
|
455
|
+
]
|
|
456
|
+
);
|
|
457
|
+
|
|
458
|
+
$.append($$anchor, rect);
|
|
459
|
+
});
|
|
460
|
+
|
|
461
|
+
var node_4 = $.sibling(node_3);
|
|
462
|
+
|
|
463
|
+
$.each(node_4, 17, () => $.get(diamond_dat).filter((d) => filter_labs(d, $.get(relevant_types))), $.index, ($$anchor, d) => {
|
|
464
|
+
var g_1 = root_2$3();
|
|
465
|
+
var text = $.child(g_1);
|
|
466
|
+
var text_1 = $.child(text, true);
|
|
467
|
+
|
|
468
|
+
$.reset(text);
|
|
469
|
+
$.reset(g_1);
|
|
470
|
+
|
|
471
|
+
$.template_effect(
|
|
472
|
+
($0, $1, $2, $3, $4, $5) => {
|
|
473
|
+
$.set_attribute(g_1, 'transform', `
|
|
474
|
+
scale(1,-1)
|
|
475
|
+
rotate(-90)
|
|
476
|
+
rotate(-45, ${$0 ?? ''}, ${$1 ?? ''})
|
|
477
|
+
translate(${$2 ?? ''}, 0)
|
|
478
|
+
`);
|
|
479
|
+
|
|
480
|
+
$.set_attribute(text, 'x', $3);
|
|
481
|
+
$.set_attribute(text, 'y', $4);
|
|
482
|
+
$.set_attribute(text, 'text-anchor', $.get(d).x1 - $.get(d).y1 <= 0 ? "start" : "end");
|
|
483
|
+
$.set_text(text_1, $5);
|
|
484
|
+
},
|
|
485
|
+
[
|
|
486
|
+
() => $.get(xy)($.get(d).x1),
|
|
487
|
+
() => $.get(xy)($.get(d).y1),
|
|
488
|
+
() => $.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,
|
|
489
|
+
() => $.get(xy)($.get(d).x1),
|
|
490
|
+
() => Number.isInteger($.get(d).coord_on_diag) ? $.get(xy)($.get(d).y1) : $.get(xy)($.get(d).y1) - 1,
|
|
491
|
+
() => $.get(d).types.split(",")[0]
|
|
492
|
+
]
|
|
493
|
+
);
|
|
494
|
+
|
|
495
|
+
$.append($$anchor, g_1);
|
|
496
|
+
});
|
|
497
|
+
|
|
498
|
+
var node_5 = $.sibling(node_4);
|
|
499
|
+
|
|
500
|
+
Contours(node_5, {
|
|
501
|
+
get alpha() {
|
|
502
|
+
return $$props.alpha;
|
|
503
|
+
},
|
|
504
|
+
get maxlog10() {
|
|
505
|
+
return $$props.maxlog10;
|
|
506
|
+
},
|
|
507
|
+
get divnorm() {
|
|
508
|
+
return $$props.divnorm;
|
|
509
|
+
},
|
|
510
|
+
get DiamondInnerHeight() {
|
|
511
|
+
return $.get(innerHeight);
|
|
512
|
+
}
|
|
513
|
+
});
|
|
514
|
+
|
|
515
|
+
$.reset(g);
|
|
516
|
+
|
|
517
|
+
$.template_effect(() => {
|
|
518
|
+
$.set_attribute(g, 'transform', `translate(360, 0) scale (-1,1) rotate(45) translate(${$.get(innerHeight) / 4}, ${$.get(innerHeight) / 4})`);
|
|
519
|
+
$.set_attribute(polygon, 'points', $.get(blue_triangle));
|
|
520
|
+
$.set_attribute(polygon_1, 'points', $.get(grey_triangle));
|
|
521
|
+
});
|
|
522
|
+
|
|
523
|
+
$.append($$anchor, g);
|
|
524
|
+
$.pop();
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
var root_1$2 = $.from_svg(`<g class="tick"><line y1="0" stroke="currentColor" stroke-opacity="0.1"></line><text y="-12" font-size="0.8em" text-anchor="middle"> </text></g>`);
|
|
528
|
+
var root_2$2 = $.from_svg(`<rect></rect>`);
|
|
529
|
+
var root_3$2 = $.from_svg(`<text dy="0.35em" font-size="0.7em"> </text>`);
|
|
530
|
+
var root$3 = $.from_svg(`<g class="wordshift-container svelte-48jn79"><g class="axis x"><!><text y="-22" fill="currentColor" text-anchor="center" font-size="0.9em"> </text></g><!><g class="y-axis"></g></g>`);
|
|
531
|
+
|
|
532
|
+
function Wordshift($$anchor, $$props) {
|
|
533
|
+
$.push($$props, true);
|
|
534
|
+
|
|
535
|
+
let x = $.prop($$props, 'x', 3, (d) => d.metric),
|
|
536
|
+
y = $.prop($$props, 'y', 3, (d) => d.type),
|
|
537
|
+
marginTop = $.prop($$props, 'marginTop', 3, 30),
|
|
538
|
+
marginRight = $.prop($$props, 'marginRight', 3, 40),
|
|
539
|
+
marginBottom = $.prop($$props, 'marginBottom', 3, 10),
|
|
540
|
+
marginLeft = $.prop($$props, 'marginLeft', 3, 40),
|
|
541
|
+
width = $.prop($$props, 'width', 3, 300);
|
|
542
|
+
$.prop($$props, 'height', 3, 680);
|
|
543
|
+
let xFormat = $.prop($$props, 'xFormat', 3, '%'),
|
|
544
|
+
xLabel = $.prop($$props, 'xLabel', 3, '← System 1 · Divergence contribution · System 2 →'),
|
|
545
|
+
yPadding = $.prop($$props, 'yPadding', 3, 0.2),
|
|
546
|
+
colors = $.prop($$props, 'colors', 19, () => ['lightgrey', 'lightblue']);
|
|
547
|
+
|
|
548
|
+
// Compute values (matching D3 version)
|
|
549
|
+
let X = $.derived(() => d3.map($$props.barData, x()));
|
|
550
|
+
let Y = $.derived(() => d3.map($$props.barData, y()));
|
|
551
|
+
// Compute domains
|
|
552
|
+
let computedXDomain = $.derived(() => $$props.xDomain || d3.extent($.get(X)));
|
|
553
|
+
let yDomain = $.derived(() => new d3.InternSet($.get(Y)));
|
|
554
|
+
|
|
555
|
+
// Compute dimensions
|
|
556
|
+
let xRange = $.derived(() => [
|
|
557
|
+
marginLeft(),
|
|
558
|
+
width() - marginRight()
|
|
559
|
+
]);
|
|
560
|
+
|
|
561
|
+
let computedHeight = $.derived(() => Math.ceil(($.get(yDomain).size + yPadding()) * 25) + marginTop() + marginBottom());
|
|
562
|
+
|
|
563
|
+
let yRange = $.derived(() => [
|
|
564
|
+
marginTop(),
|
|
565
|
+
$.get(computedHeight) - marginBottom()
|
|
566
|
+
]);
|
|
567
|
+
|
|
568
|
+
// Filter indices and create lookup
|
|
569
|
+
let I = $.derived(() => d3.range($.get(X).length).filter((i) => $.get(yDomain).has($.get(Y)[i])));
|
|
570
|
+
let YX = $.derived(() => d3.rollup($.get(I), ([i]) => $.get(X)[i], (i) => $.get(Y)[i]));
|
|
571
|
+
// Scales
|
|
572
|
+
let xScale = $.derived(() => d3.scaleLinear($.get(computedXDomain), $.get(xRange)));
|
|
573
|
+
let yScale = $.derived(() => d3.scaleBand().domain($.get(yDomain)).range($.get(yRange)).padding(yPadding()));
|
|
574
|
+
let format = $.derived(() => $.get(xScale).tickFormat(100, xFormat()));
|
|
575
|
+
let xTicks = $.derived(() => $.get(xScale).ticks(width() / 80));
|
|
576
|
+
// Position the chart (matching your current positioning)
|
|
577
|
+
let chartX = $.derived(() => $$props.DashboardWidth - width() + marginLeft());
|
|
578
|
+
let chartY = $.derived(marginTop);
|
|
579
|
+
var g = root$3();
|
|
580
|
+
var g_1 = $.child(g);
|
|
581
|
+
var node = $.child(g_1);
|
|
582
|
+
|
|
583
|
+
$.each(node, 17, () => $.get(xTicks), $.index, ($$anchor, tick) => {
|
|
584
|
+
var g_2 = root_1$2();
|
|
585
|
+
var line = $.child(g_2);
|
|
586
|
+
var text = $.sibling(line);
|
|
587
|
+
var text_1 = $.child(text, true);
|
|
588
|
+
|
|
589
|
+
$.reset(text);
|
|
590
|
+
$.reset(g_2);
|
|
591
|
+
|
|
592
|
+
$.template_effect(
|
|
593
|
+
($0, $1, $2, $3) => {
|
|
594
|
+
$.set_attribute(line, 'x1', $0);
|
|
595
|
+
$.set_attribute(line, 'x2', $1);
|
|
596
|
+
$.set_attribute(line, 'y2', $.get(computedHeight) - marginTop() - marginBottom());
|
|
597
|
+
$.set_attribute(text, 'x', $2);
|
|
598
|
+
$.set_text(text_1, $3);
|
|
599
|
+
},
|
|
600
|
+
[
|
|
601
|
+
() => $.get(xScale)($.get(tick)),
|
|
602
|
+
() => $.get(xScale)($.get(tick)),
|
|
603
|
+
() => $.get(xScale)($.get(tick)),
|
|
604
|
+
() => $.get(format)($.get(tick))
|
|
605
|
+
]
|
|
606
|
+
);
|
|
607
|
+
|
|
608
|
+
$.append($$anchor, g_2);
|
|
609
|
+
});
|
|
610
|
+
|
|
611
|
+
var text_2 = $.sibling(node);
|
|
612
|
+
var text_3 = $.child(text_2, true);
|
|
613
|
+
|
|
614
|
+
$.reset(text_2);
|
|
615
|
+
$.reset(g_1);
|
|
616
|
+
|
|
617
|
+
var node_1 = $.sibling(g_1);
|
|
618
|
+
|
|
619
|
+
$.each(node_1, 17, () => $.get(I), $.index, ($$anchor, i) => {
|
|
620
|
+
var rect = root_2$2();
|
|
621
|
+
|
|
622
|
+
$.template_effect(
|
|
623
|
+
($0, $1, $2, $3) => {
|
|
624
|
+
$.set_attribute(rect, 'x', $0);
|
|
625
|
+
$.set_attribute(rect, 'y', $1);
|
|
626
|
+
$.set_attribute(rect, 'fill', colors()[$.get(X)[$.get(i)] > 0 ? colors().length - 1 : 0]);
|
|
627
|
+
$.set_attribute(rect, 'width', $2);
|
|
628
|
+
$.set_attribute(rect, 'height', $3);
|
|
629
|
+
},
|
|
630
|
+
[
|
|
631
|
+
() => Math.min($.get(xScale)(0), $.get(xScale)($.get(X)[$.get(i)])),
|
|
632
|
+
() => $.get(yScale)($.get(Y)[$.get(i)]),
|
|
633
|
+
() => Math.abs($.get(xScale)($.get(X)[$.get(i)]) - $.get(xScale)(0)),
|
|
634
|
+
() => $.get(yScale).bandwidth()
|
|
635
|
+
]
|
|
636
|
+
);
|
|
637
|
+
|
|
638
|
+
$.append($$anchor, rect);
|
|
639
|
+
});
|
|
640
|
+
|
|
641
|
+
var g_3 = $.sibling(node_1);
|
|
642
|
+
|
|
643
|
+
$.each(g_3, 21, () => $.get(yScale).domain(), $.index, ($$anchor, label) => {
|
|
644
|
+
var text_4 = root_3$2();
|
|
645
|
+
var text_5 = $.child(text_4, true);
|
|
646
|
+
|
|
647
|
+
$.reset(text_4);
|
|
648
|
+
|
|
649
|
+
$.template_effect(
|
|
650
|
+
($0, $1, $2) => {
|
|
651
|
+
$.set_attribute(text_4, 'x', $0);
|
|
652
|
+
$.set_attribute(text_4, 'y', $1);
|
|
653
|
+
$.set_attribute(text_4, 'text-anchor', $2);
|
|
654
|
+
$.set_text(text_5, $.get(label));
|
|
655
|
+
},
|
|
656
|
+
[
|
|
657
|
+
() => $.get(YX).get($.get(label)) > 0 ? 6 : -6,
|
|
658
|
+
() => $.get(yScale)($.get(label)) + $.get(yScale).bandwidth() / 2,
|
|
659
|
+
() => $.get(YX).get($.get(label)) > 0 ? "start" : "end"
|
|
660
|
+
]
|
|
661
|
+
);
|
|
662
|
+
|
|
663
|
+
$.append($$anchor, text_4);
|
|
664
|
+
});
|
|
665
|
+
|
|
666
|
+
$.reset(g_3);
|
|
667
|
+
$.reset(g);
|
|
668
|
+
|
|
669
|
+
$.template_effect(
|
|
670
|
+
($0, $1) => {
|
|
671
|
+
$.set_attribute(g, 'transform', `translate(${$.get(chartX) ?? ''}, ${$.get(chartY) ?? ''})`);
|
|
672
|
+
$.set_attribute(g_1, 'transform', `translate(0, ${marginTop() ?? ''})`);
|
|
673
|
+
$.set_attribute(text_2, 'x', $0);
|
|
674
|
+
$.set_text(text_3, xLabel());
|
|
675
|
+
$.set_attribute(g_3, 'transform', `translate(${$1 ?? ''}, 0)`);
|
|
676
|
+
},
|
|
677
|
+
[
|
|
678
|
+
() => $.get(xScale)(0),
|
|
679
|
+
() => $.get(xScale)(0)
|
|
680
|
+
]
|
|
681
|
+
);
|
|
682
|
+
|
|
683
|
+
$.append($$anchor, g);
|
|
684
|
+
$.pop();
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
var root_1$1 = $.from_svg(`<line y1="0" stroke="currentColor" stroke-opacity="0.1"></line>`);
|
|
688
|
+
var root_2$1 = $.from_svg(`<rect></rect><text opacity="0.5" dy="0.35em" font-size="10" font-family="sans-serif"> </text>`, 1);
|
|
689
|
+
var root_3$1 = $.from_svg(`<text x="0" dy="0.35em" font-size="10" font-family="sans-serif" text-anchor="middle"> </text>`);
|
|
690
|
+
var root$2 = $.from_svg(`<g class="balance-chart"><g class="grid"></g><!><g class="y-axis"></g></g>`);
|
|
691
|
+
|
|
692
|
+
function DivergingBarChart($$anchor, $$props) {
|
|
693
|
+
$.push($$props, true);
|
|
694
|
+
|
|
695
|
+
let x = $.prop($$props, 'x', 3, (d) => d.frequency),
|
|
696
|
+
y = $.prop($$props, 'y', 3, (d) => d.y_coord),
|
|
697
|
+
marginTop = $.prop($$props, 'marginTop', 3, 0),
|
|
698
|
+
marginRight = $.prop($$props, 'marginRight', 3, 40),
|
|
699
|
+
marginBottom = $.prop($$props, 'marginBottom', 3, 10),
|
|
700
|
+
marginLeft = $.prop($$props, 'marginLeft', 3, 40),
|
|
701
|
+
width = $.prop($$props, 'width', 3, 200),
|
|
702
|
+
yPadding = $.prop($$props, 'yPadding', 3, 0.5),
|
|
703
|
+
colors = $.prop($$props, 'colors', 19, () => ["lightgrey", "lightblue"]);
|
|
704
|
+
|
|
705
|
+
// Compute values (matching D3 version exactly)
|
|
706
|
+
let X = $.derived(() => map($$props.data, x()));
|
|
707
|
+
let Y = $.derived(() => map($$props.data, y()));
|
|
708
|
+
// Compute domains
|
|
709
|
+
let xDomain = $.derived(() => extent($.get(X)));
|
|
710
|
+
let yDomain = $.derived(() => new InternSet($.get(Y)));
|
|
711
|
+
|
|
712
|
+
// Compute dimensions
|
|
713
|
+
let xRange = $.derived(() => [
|
|
714
|
+
marginLeft(),
|
|
715
|
+
width() - marginRight()
|
|
716
|
+
]);
|
|
717
|
+
|
|
718
|
+
let height = $.derived(() => Math.ceil(($.get(yDomain).size + yPadding()) * 25) + marginTop() + marginBottom());
|
|
719
|
+
|
|
720
|
+
let yRange = $.derived(() => [
|
|
721
|
+
marginTop(),
|
|
722
|
+
$.get(height) - marginBottom()
|
|
723
|
+
]);
|
|
724
|
+
|
|
725
|
+
// Filter indices and create lookup
|
|
726
|
+
let I = $.derived(() => range($.get(X).length).filter((i) => $.get(yDomain).has($.get(Y)[i])));
|
|
727
|
+
let YX = $.derived(() => rollup($.get(I), ([i]) => $.get(X)[i], (i) => $.get(Y)[i]));
|
|
728
|
+
// Scales
|
|
729
|
+
let xScale = $.derived(() => scaleLinear($.get(xDomain), $.get(xRange)));
|
|
730
|
+
let yScale = $.derived(() => scaleBand().domain($.get(yDomain)).range($.get(yRange)).padding(yPadding()));
|
|
731
|
+
let format = $.derived(() => $.get(xScale).tickFormat(100, "%"));
|
|
732
|
+
var g = root$2();
|
|
733
|
+
var g_1 = $.child(g);
|
|
734
|
+
|
|
735
|
+
$.each(g_1, 21, () => $.get(xScale).ticks(width() / 80), $.index, ($$anchor, tick) => {
|
|
736
|
+
var line = root_1$1();
|
|
737
|
+
|
|
738
|
+
$.template_effect(
|
|
739
|
+
($0, $1) => {
|
|
740
|
+
$.set_attribute(line, 'x1', $0);
|
|
741
|
+
$.set_attribute(line, 'x2', $1);
|
|
742
|
+
$.set_attribute(line, 'y2', $.get(height) - marginTop() - marginBottom());
|
|
743
|
+
},
|
|
744
|
+
[
|
|
745
|
+
() => $.get(xScale)($.get(tick)),
|
|
746
|
+
() => $.get(xScale)($.get(tick))
|
|
747
|
+
]
|
|
748
|
+
);
|
|
749
|
+
|
|
750
|
+
$.append($$anchor, line);
|
|
751
|
+
});
|
|
752
|
+
|
|
753
|
+
$.reset(g_1);
|
|
754
|
+
|
|
755
|
+
var node = $.sibling(g_1);
|
|
756
|
+
|
|
757
|
+
$.each(node, 17, () => $.get(I), $.index, ($$anchor, i) => {
|
|
758
|
+
var fragment = root_2$1();
|
|
759
|
+
var rect = $.first_child(fragment);
|
|
760
|
+
var text = $.sibling(rect);
|
|
761
|
+
var text_1 = $.child(text, true);
|
|
762
|
+
|
|
763
|
+
$.reset(text);
|
|
764
|
+
|
|
765
|
+
$.template_effect(
|
|
766
|
+
($0, $1, $2, $3, $4, $5, $6) => {
|
|
767
|
+
$.set_attribute(rect, 'x', $0);
|
|
768
|
+
$.set_attribute(rect, 'y', $1);
|
|
769
|
+
$.set_attribute(rect, 'fill', colors()[$.get(X)[$.get(i)] > 0 ? colors().length - 1 : 0]);
|
|
770
|
+
$.set_attribute(rect, 'width', $2);
|
|
771
|
+
$.set_attribute(rect, 'height', $3);
|
|
772
|
+
$.set_attribute(text, 'x', $4);
|
|
773
|
+
$.set_attribute(text, 'y', $5);
|
|
774
|
+
$.set_attribute(text, 'text-anchor', $.get(X)[$.get(i)] < 0 ? "end" : "start");
|
|
775
|
+
$.set_text(text_1, $6);
|
|
776
|
+
},
|
|
777
|
+
[
|
|
778
|
+
() => Math.min($.get(xScale)(0), $.get(xScale)($.get(X)[$.get(i)])),
|
|
779
|
+
() => $.get(yScale)($.get(Y)[$.get(i)]),
|
|
780
|
+
() => Math.abs($.get(xScale)($.get(X)[$.get(i)]) - $.get(xScale)(0)),
|
|
781
|
+
() => $.get(yScale).bandwidth(),
|
|
782
|
+
() => $.get(xScale)($.get(X)[$.get(i)]) + Math.sign($.get(X)[$.get(i)] - 0) * 4,
|
|
783
|
+
() => $.get(yScale)($.get(Y)[$.get(i)]) + $.get(yScale).bandwidth() / 2,
|
|
784
|
+
() => $.get(format)(Math.abs($.get(X)[$.get(i)]))
|
|
785
|
+
]
|
|
786
|
+
);
|
|
787
|
+
|
|
788
|
+
$.append($$anchor, fragment);
|
|
789
|
+
});
|
|
790
|
+
|
|
791
|
+
var g_2 = $.sibling(node);
|
|
792
|
+
|
|
793
|
+
$.each(g_2, 21, () => $.get(yScale).domain(), $.index, ($$anchor, label) => {
|
|
794
|
+
var text_2 = root_3$1();
|
|
795
|
+
var text_3 = $.child(text_2, true);
|
|
796
|
+
|
|
797
|
+
$.reset(text_2);
|
|
798
|
+
|
|
799
|
+
$.template_effect(
|
|
800
|
+
($0, $1) => {
|
|
801
|
+
$.set_attribute(text_2, 'y', $0);
|
|
802
|
+
$.set_attribute(text_2, 'opacity', $1);
|
|
803
|
+
$.set_text(text_3, $.get(label));
|
|
804
|
+
},
|
|
805
|
+
[
|
|
806
|
+
() => $.get(yScale)($.get(label)) + $.get(yScale).bandwidth() / 2,
|
|
807
|
+
() => $.get(YX).get($.get(label)) ? "0.5" : "1"
|
|
808
|
+
]
|
|
809
|
+
);
|
|
810
|
+
|
|
811
|
+
$.append($$anchor, text_2);
|
|
812
|
+
});
|
|
813
|
+
|
|
814
|
+
$.reset(g_2);
|
|
815
|
+
$.reset(g);
|
|
816
|
+
|
|
817
|
+
$.template_effect(
|
|
818
|
+
($0) => {
|
|
819
|
+
$.set_attribute(g, 'transform', `translate(${$$props.DiamondWidth - 75}, ${$$props.DiamondHeight + 75})`);
|
|
820
|
+
$.set_attribute(g_1, 'transform', `translate(0,${marginTop() ?? ''})`);
|
|
821
|
+
$.set_attribute(g_2, 'transform', `translate(${$0 ?? ''},-12)`);
|
|
822
|
+
},
|
|
823
|
+
[() => $.get(xScale)(0)]
|
|
824
|
+
);
|
|
825
|
+
|
|
826
|
+
$.append($$anchor, g);
|
|
827
|
+
$.pop();
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
var root_1 = $.from_svg(`<rect stroke="whitesmoke" stroke-width="1"></rect>`);
|
|
831
|
+
var root_3 = $.from_svg(`<g class="legend-title"><text font-size="13">Counts per cell</text></g>`);
|
|
832
|
+
var root_2 = $.from_svg(`<g class="legend-text"><text font-size="10" dx="20"> </text></g><!>`, 1);
|
|
833
|
+
var root$1 = $.from_svg(`<g class="legend-container"></g><!>`, 1);
|
|
834
|
+
|
|
835
|
+
function Legend($$anchor, $$props) {
|
|
836
|
+
$.push($$props, true);
|
|
837
|
+
|
|
838
|
+
const N_CATEGO = 20;
|
|
839
|
+
const myramp = range(N_CATEGO).map((i) => rgb(interpolateInferno(i / (N_CATEGO - 1))).hex());
|
|
840
|
+
const color = scaleOrdinal(range(N_CATEGO), myramp);
|
|
841
|
+
let height = 370;
|
|
842
|
+
const margin = { right: 40, top: 65, left: 10 };
|
|
843
|
+
let innerHeight = $.derived(() => height - margin.top - margin.right);
|
|
844
|
+
let max_rank = $.derived(() => max($$props.diamond_dat, (d) => d.rank_L[1]));
|
|
845
|
+
let y = $.derived(() => scaleBand().domain(color.domain().reverse()).rangeRound([0, $.get(innerHeight)]));
|
|
846
|
+
// Use max_count_log if provided, otherwise calculate from data
|
|
847
|
+
let logDomain = $.derived(() => $$props.max_count_log || 10 ** Math.ceil(Math.log10($.get(max_rank)) - 1));
|
|
848
|
+
let logY = $.derived(() => scaleLog().domain([1, $.get(logDomain)]).rangeRound([0, $.get(innerHeight)]).nice());
|
|
849
|
+
let logFormat10 = $.derived(() => $.get(logY).tickFormat());
|
|
850
|
+
let yTicks = $.derived(() => $.get(logY).ticks());
|
|
851
|
+
var fragment = root$1();
|
|
852
|
+
var g = $.first_child(fragment);
|
|
853
|
+
|
|
854
|
+
$.each(g, 21, () => color.domain(), $.index, ($$anchor, d) => {
|
|
855
|
+
var rect = root_1();
|
|
856
|
+
|
|
857
|
+
$.set_attribute(rect, 'x', 0);
|
|
858
|
+
$.set_attribute(rect, 'width', 14);
|
|
859
|
+
$.set_attribute(rect, 'height', 13);
|
|
860
|
+
|
|
861
|
+
$.template_effect(
|
|
862
|
+
($0, $1) => {
|
|
863
|
+
$.set_attribute(rect, 'y', $0);
|
|
864
|
+
$.set_attribute(rect, 'fill', $1);
|
|
865
|
+
},
|
|
866
|
+
[
|
|
867
|
+
() => $.get(y)($.get(d)),
|
|
868
|
+
() => color($.get(d))
|
|
869
|
+
]
|
|
870
|
+
);
|
|
871
|
+
|
|
872
|
+
$.append($$anchor, rect);
|
|
873
|
+
});
|
|
874
|
+
|
|
875
|
+
$.reset(g);
|
|
876
|
+
|
|
877
|
+
var node = $.sibling(g);
|
|
878
|
+
|
|
879
|
+
$.each(node, 17, () => $.get(yTicks), $.index, ($$anchor, tick, i) => {
|
|
880
|
+
var fragment_1 = root_2();
|
|
881
|
+
var g_1 = $.first_child(fragment_1);
|
|
882
|
+
var text = $.child(g_1);
|
|
883
|
+
var text_1 = $.child(text, true);
|
|
884
|
+
|
|
885
|
+
$.reset(text);
|
|
886
|
+
$.reset(g_1);
|
|
887
|
+
|
|
888
|
+
var node_1 = $.sibling(g_1);
|
|
889
|
+
|
|
890
|
+
{
|
|
891
|
+
var consequent = ($$anchor) => {
|
|
892
|
+
var g_2 = root_3();
|
|
893
|
+
var text_2 = $.child(g_2);
|
|
894
|
+
|
|
895
|
+
$.set_attribute(text_2, 'dy', "9");
|
|
896
|
+
$.reset(g_2);
|
|
897
|
+
|
|
898
|
+
$.template_effect(($0) => $.set_attribute(g_2, 'transform', `translate(${margin.left}, ${$0 ?? ''})`), [
|
|
899
|
+
() => $$props.DiamondHeight + $.get(logY)($.get(tick)) - margin.top
|
|
900
|
+
]);
|
|
901
|
+
|
|
902
|
+
$.append($$anchor, g_2);
|
|
903
|
+
};
|
|
904
|
+
|
|
905
|
+
$.if(node_1, ($$render) => {
|
|
906
|
+
if (i === $.get(yTicks).length - 1) $$render(consequent);
|
|
907
|
+
});
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
$.template_effect(
|
|
911
|
+
($0, $1) => {
|
|
912
|
+
$.set_attribute(g_1, 'transform', `translate(${margin.left}, ${$0 ?? ''})`);
|
|
913
|
+
$.set_attribute(text, 'dy', $.get(yTicks).length - 1 == i ? "-3" : "13");
|
|
914
|
+
$.set_text(text_1, $1);
|
|
915
|
+
},
|
|
916
|
+
[
|
|
917
|
+
() => $$props.DiamondHeight + $.get(logY)($.get(tick)) - margin.top,
|
|
918
|
+
() => $.get(logFormat10)($.get(tick))
|
|
919
|
+
]
|
|
920
|
+
);
|
|
921
|
+
|
|
922
|
+
$.append($$anchor, fragment_1);
|
|
923
|
+
});
|
|
924
|
+
|
|
925
|
+
$.template_effect(() => $.set_attribute(g, 'transform', `translate(${margin.left}, ${$$props.DiamondHeight - margin.top})`));
|
|
926
|
+
$.append($$anchor, fragment);
|
|
927
|
+
$.pop();
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
var root = $.from_html(`<div><svg id="allotaxonometer-svg" class="svelte-n6o6ey"><!><!><!><!></svg></div>`);
|
|
931
|
+
|
|
932
|
+
function Dashboard($$anchor, $$props) {
|
|
933
|
+
$.push($$props, true);
|
|
934
|
+
|
|
935
|
+
let dat = $.prop($$props, 'dat', 3, null),
|
|
936
|
+
alpha = $.prop($$props, 'alpha', 3, 0.58),
|
|
937
|
+
divnorm = $.prop($$props, 'divnorm', 3, 1),
|
|
938
|
+
barData = $.prop($$props, 'barData', 19, () => []),
|
|
939
|
+
balanceData = $.prop($$props, 'balanceData', 19, () => []),
|
|
940
|
+
xDomain = $.prop($$props, 'xDomain', 3, undefined),
|
|
941
|
+
title = $.prop($$props, 'title', 19, () => ['System 1', 'System 2']),
|
|
942
|
+
maxlog10 = $.prop($$props, 'maxlog10', 3, 0),
|
|
943
|
+
height = $.prop($$props, 'height', 3, 815),
|
|
944
|
+
width = $.prop($$props, 'width', 3, 1200),
|
|
945
|
+
DashboardHeight = $.prop($$props, 'DashboardHeight', 3, 815),
|
|
946
|
+
DashboardWidth = $.prop($$props, 'DashboardWidth', 3, 1200),
|
|
947
|
+
DiamondHeight = $.prop($$props, 'DiamondHeight', 3, 600),
|
|
948
|
+
DiamondWidth = $.prop($$props, 'DiamondWidth', 3, 600),
|
|
949
|
+
marginInner = $.prop($$props, 'marginInner', 3, 160),
|
|
950
|
+
marginDiamond = $.prop($$props, 'marginDiamond', 3, 40),
|
|
951
|
+
max_count_log = $.prop($$props, 'max_count_log', 3, undefined),
|
|
952
|
+
className = $.prop($$props, 'class', 3, ''),
|
|
953
|
+
style = $.prop($$props, 'style', 3, ''),
|
|
954
|
+
showDiamond = $.prop($$props, 'showDiamond', 3, true),
|
|
955
|
+
showWordshift = $.prop($$props, 'showWordshift', 3, true),
|
|
956
|
+
showDivergingBar = $.prop($$props, 'showDivergingBar', 3, true),
|
|
957
|
+
showLegend = $.prop($$props, 'showLegend', 3, true),
|
|
958
|
+
restProps = $.rest_props($$props, [
|
|
959
|
+
'$$slots',
|
|
960
|
+
'$$events',
|
|
961
|
+
'$$legacy',
|
|
962
|
+
'dat',
|
|
963
|
+
'alpha',
|
|
964
|
+
'divnorm',
|
|
965
|
+
'barData',
|
|
966
|
+
'balanceData',
|
|
967
|
+
'xDomain',
|
|
968
|
+
'title',
|
|
969
|
+
'maxlog10',
|
|
970
|
+
'height',
|
|
971
|
+
'width',
|
|
972
|
+
'DashboardHeight',
|
|
973
|
+
'DashboardWidth',
|
|
974
|
+
'DiamondHeight',
|
|
975
|
+
'DiamondWidth',
|
|
976
|
+
'marginInner',
|
|
977
|
+
'marginDiamond',
|
|
978
|
+
'max_count_log',
|
|
979
|
+
'class',
|
|
980
|
+
'style',
|
|
981
|
+
'showDiamond',
|
|
982
|
+
'showWordshift',
|
|
983
|
+
'showDivergingBar',
|
|
984
|
+
'showLegend'
|
|
985
|
+
]);
|
|
986
|
+
|
|
987
|
+
let max_shift = $.derived(() => barData().length > 0 ? Math.max(...barData().map((d) => Math.abs(d.metric))) : 1);
|
|
988
|
+
|
|
989
|
+
let wordshiftXDomain = $.derived(() => xDomain() || [
|
|
990
|
+
-$.get(max_shift) * 1.5,
|
|
991
|
+
$.get(max_shift) * 1.5
|
|
992
|
+
]);
|
|
993
|
+
|
|
994
|
+
var div = root();
|
|
995
|
+
|
|
996
|
+
$.attribute_effect(
|
|
997
|
+
div,
|
|
998
|
+
() => ({
|
|
999
|
+
class: `allotaxonometer-dashboard ${className() ?? ''}`,
|
|
1000
|
+
style: style(),
|
|
1001
|
+
...restProps
|
|
1002
|
+
}),
|
|
1003
|
+
undefined,
|
|
1004
|
+
'svelte-n6o6ey'
|
|
1005
|
+
);
|
|
1006
|
+
|
|
1007
|
+
var svg = $.child(div);
|
|
1008
|
+
var node = $.child(svg);
|
|
1009
|
+
|
|
1010
|
+
{
|
|
1011
|
+
var consequent = ($$anchor) => {
|
|
1012
|
+
Diamond($$anchor, {
|
|
1013
|
+
get dat() {
|
|
1014
|
+
return dat();
|
|
1015
|
+
},
|
|
1016
|
+
get alpha() {
|
|
1017
|
+
return alpha();
|
|
1018
|
+
},
|
|
1019
|
+
get divnorm() {
|
|
1020
|
+
return divnorm();
|
|
1021
|
+
},
|
|
1022
|
+
get title() {
|
|
1023
|
+
return title();
|
|
1024
|
+
},
|
|
1025
|
+
get maxlog10() {
|
|
1026
|
+
return maxlog10();
|
|
1027
|
+
},
|
|
1028
|
+
get DiamondHeight() {
|
|
1029
|
+
return DiamondHeight();
|
|
1030
|
+
},
|
|
1031
|
+
get marginInner() {
|
|
1032
|
+
return marginInner();
|
|
1033
|
+
},
|
|
1034
|
+
get marginDiamond() {
|
|
1035
|
+
return marginDiamond();
|
|
1036
|
+
}
|
|
1037
|
+
});
|
|
1038
|
+
};
|
|
1039
|
+
|
|
1040
|
+
$.if(node, ($$render) => {
|
|
1041
|
+
if (showDiamond() && dat()) $$render(consequent);
|
|
1042
|
+
});
|
|
1043
|
+
}
|
|
1044
|
+
|
|
1045
|
+
var node_1 = $.sibling(node);
|
|
1046
|
+
|
|
1047
|
+
{
|
|
1048
|
+
var consequent_1 = ($$anchor) => {
|
|
1049
|
+
Wordshift($$anchor, {
|
|
1050
|
+
get barData() {
|
|
1051
|
+
return barData();
|
|
1052
|
+
},
|
|
1053
|
+
get DashboardHeight() {
|
|
1054
|
+
return DashboardHeight();
|
|
1055
|
+
},
|
|
1056
|
+
get DashboardWidth() {
|
|
1057
|
+
return DashboardWidth();
|
|
1058
|
+
},
|
|
1059
|
+
get xDomain() {
|
|
1060
|
+
return $.get(wordshiftXDomain);
|
|
1061
|
+
},
|
|
1062
|
+
width: 640,
|
|
1063
|
+
marginLeft: 140
|
|
1064
|
+
});
|
|
1065
|
+
};
|
|
1066
|
+
|
|
1067
|
+
$.if(node_1, ($$render) => {
|
|
1068
|
+
if (showWordshift() && barData().length > 0) $$render(consequent_1);
|
|
1069
|
+
});
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
var node_2 = $.sibling(node_1);
|
|
1073
|
+
|
|
1074
|
+
{
|
|
1075
|
+
var consequent_2 = ($$anchor) => {
|
|
1076
|
+
DivergingBarChart($$anchor, {
|
|
1077
|
+
get data() {
|
|
1078
|
+
return balanceData();
|
|
1079
|
+
},
|
|
1080
|
+
get DiamondHeight() {
|
|
1081
|
+
return DiamondHeight();
|
|
1082
|
+
},
|
|
1083
|
+
get DiamondWidth() {
|
|
1084
|
+
return DiamondWidth();
|
|
1085
|
+
}
|
|
1086
|
+
});
|
|
1087
|
+
};
|
|
1088
|
+
|
|
1089
|
+
$.if(node_2, ($$render) => {
|
|
1090
|
+
if (showDivergingBar() && balanceData().length > 0) $$render(consequent_2);
|
|
1091
|
+
});
|
|
1092
|
+
}
|
|
1093
|
+
|
|
1094
|
+
var node_3 = $.sibling(node_2);
|
|
1095
|
+
|
|
1096
|
+
{
|
|
1097
|
+
var consequent_3 = ($$anchor) => {
|
|
1098
|
+
Legend($$anchor, {
|
|
1099
|
+
get diamond_dat() {
|
|
1100
|
+
return dat().counts;
|
|
1101
|
+
},
|
|
1102
|
+
get DiamondHeight() {
|
|
1103
|
+
return DiamondHeight();
|
|
1104
|
+
},
|
|
1105
|
+
get max_count_log() {
|
|
1106
|
+
return max_count_log();
|
|
1107
|
+
}
|
|
1108
|
+
});
|
|
1109
|
+
};
|
|
1110
|
+
|
|
1111
|
+
$.if(node_3, ($$render) => {
|
|
1112
|
+
if (showLegend() && dat()) $$render(consequent_3);
|
|
1113
|
+
});
|
|
1114
|
+
}
|
|
1115
|
+
|
|
1116
|
+
$.reset(svg);
|
|
1117
|
+
$.reset(div);
|
|
1118
|
+
|
|
1119
|
+
$.template_effect(() => {
|
|
1120
|
+
$.set_attribute(svg, 'height', height());
|
|
1121
|
+
$.set_attribute(svg, 'width', width());
|
|
1122
|
+
});
|
|
1123
|
+
|
|
1124
|
+
$.append($$anchor, div);
|
|
1125
|
+
$.pop();
|
|
1126
|
+
}
|
|
1127
|
+
|
|
1128
|
+
// Takes arrays, returns a Set object containing the union of both arrays
|
|
1129
|
+
function getUnions(x,y) {
|
|
1130
|
+
let a = new Set(x); // convert array x to a Set object
|
|
1131
|
+
let b = new Set(y); // convert array y to a Set object
|
|
1132
|
+
return new Set([...a, ...b]); // return a new Set object containing the union of a and b
|
|
1133
|
+
}
|
|
1134
|
+
|
|
1135
|
+
// Takes arrays, returns a Set object
|
|
1136
|
+
function setdiff(x,y) {
|
|
1137
|
+
let a = new Set(x); // convert array x to a Set object
|
|
1138
|
+
let b = new Set(y); // convert array y to a Set object
|
|
1139
|
+
// return a new Set object containing elements in a that are not present in b
|
|
1140
|
+
return new Set(
|
|
1141
|
+
[...a].filter(x => !b.has(x)));
|
|
1142
|
+
}
|
|
1143
|
+
|
|
1144
|
+
function which(x) {
|
|
1145
|
+
// Which indices are TRUE?
|
|
1146
|
+
// Description:
|
|
1147
|
+
// Give the ‘TRUE’ indices of a logical object, allowing for array indices.
|
|
1148
|
+
// Arguments:
|
|
1149
|
+
// x: a ‘logical’ vector or array.
|
|
1150
|
+
return x.reduce(
|
|
1151
|
+
(out, bool, index) => bool ? out.concat(index) : out,
|
|
1152
|
+
[]
|
|
1153
|
+
)
|
|
1154
|
+
}
|
|
1155
|
+
|
|
1156
|
+
|
|
1157
|
+
function matlab_sort(A, rev) {
|
|
1158
|
+
// Inspired by matlab, this functions keep track of the original indices of an array after sorting.
|
|
1159
|
+
// Returns both the sorted vector `v` and the original indices.
|
|
1160
|
+
//
|
|
1161
|
+
// examples
|
|
1162
|
+
// A = [5, 4, 1, 2, 3]
|
|
1163
|
+
// ([1, 2, 3, 3, 4, 5], [3, 4, 5, 6, 2, 1])
|
|
1164
|
+
|
|
1165
|
+
let sorted = rev ? A.slice().sort((a, b) => b - a) : A.slice().sort((a, b) => a - b);
|
|
1166
|
+
|
|
1167
|
+
const A_cp = A.slice();
|
|
1168
|
+
const orig_idx = [];
|
|
1169
|
+
for (let i = 0; i < A.length; ++i) {
|
|
1170
|
+
orig_idx.push(A_cp.indexOf(sorted[i]));
|
|
1171
|
+
delete A_cp[A_cp.indexOf(sorted[i])];
|
|
27
1172
|
}
|
|
28
|
-
|
|
29
|
-
|
|
1173
|
+
|
|
1174
|
+
return {'value': sorted, 'orig_idx': orig_idx}
|
|
30
1175
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
const each_array = $.ensure_array_like(xTicks);
|
|
41
|
-
$$payload.out += `<g class="axis x"${$.attr("transform", `translate(0, ${$.stringify(height)})`)}><!--[-->`;
|
|
42
|
-
for (let index = 0, $$length = each_array.length; index < $$length; index++) {
|
|
43
|
-
let tick = each_array[index];
|
|
44
|
-
$$payload.out += `<g class="xtick"${$.attr("transform", `translate(${$.stringify(scale(tick))}, 0)`)}><line x1="0" x2="0" y1="0" y2="6" stroke="hsla(212, 10%, 53%, 1)"></line></g><g class="tick-text"${$.attr("transform", `translate(${$.stringify(scale(tick))}, 0) scale(-1,1) rotate(45)`)}><text font-size="10" dx="13" dy="13">${$.escape(logFormat10(tick))}</text></g>`;
|
|
1176
|
+
|
|
1177
|
+
function tiedrank(arr) {
|
|
1178
|
+
// tiedrank(X) computes the ranks of the values in the vector X. If any X values are tied, tiedrank computes their average rank. Same as in matlab.
|
|
1179
|
+
function getIndex(arr, val) {
|
|
1180
|
+
var indexes = [], i;
|
|
1181
|
+
for(i = 0; i < arr.length; i++)
|
|
1182
|
+
if (arr[i] === val)
|
|
1183
|
+
indexes.push(i+1);
|
|
1184
|
+
return indexes.reduce((a, b) => a + b) / indexes.length;
|
|
45
1185
|
}
|
|
46
|
-
|
|
47
|
-
|
|
1186
|
+
|
|
1187
|
+
const sorted = arr.slice().sort((a, b) => b - a);
|
|
1188
|
+
return arr.map(e => getIndex(sorted, e))
|
|
1189
|
+
}
|
|
1190
|
+
|
|
1191
|
+
function rank_maxlog10(mixedelements) {
|
|
1192
|
+
// Get maximum of log10 ranks from both systems, then round up
|
|
1193
|
+
let logged_max = [
|
|
1194
|
+
Math.max(...mixedelements[[0]].ranks), Math.max(...mixedelements[[1]].ranks)
|
|
1195
|
+
].map(Math.log10);
|
|
1196
|
+
return Math.ceil(Math.max(...[logged_max[0], logged_max[1]]))
|
|
48
1197
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
1198
|
+
|
|
1199
|
+
function rin(arr1, arr2) {
|
|
1200
|
+
// Find element arr1 presents in arr2, i.e. arr1 %in% arr2
|
|
1201
|
+
//
|
|
1202
|
+
// examples
|
|
1203
|
+
// A = ["bob", "george", "jesus"]
|
|
1204
|
+
// B = ["bob", "jesus", "terrence"]
|
|
1205
|
+
// rin(A, B)
|
|
1206
|
+
// [true, false, true]
|
|
1207
|
+
return Array.from(arr1, (x) => {
|
|
1208
|
+
return arr2.indexOf(x) == -1 ? false : true
|
|
1209
|
+
})
|
|
1210
|
+
}
|
|
1211
|
+
|
|
1212
|
+
function zeros(length){
|
|
1213
|
+
// Create array of all zeros. Similar to matlab.
|
|
1214
|
+
function createArray(length) {
|
|
1215
|
+
var arr = new Array(length || 0),
|
|
1216
|
+
i = length;
|
|
1217
|
+
if (arguments.length > 1) {
|
|
1218
|
+
var args = Array.prototype.slice.call(arguments, 1);
|
|
1219
|
+
while(i--) arr[length-1 - i] = createArray.apply(this, args);
|
|
1220
|
+
}
|
|
1221
|
+
return arr;
|
|
59
1222
|
}
|
|
60
|
-
|
|
61
|
-
|
|
1223
|
+
let empty_mat = createArray(length,length);
|
|
1224
|
+
return Array.from(empty_mat, arr => arr.fill(0))
|
|
1225
|
+
}
|
|
1226
|
+
|
|
1227
|
+
// Builds a mixed element array containing the union of types in elem1 and elem2
|
|
1228
|
+
function buildMixedElems(elem1, elem2) {
|
|
1229
|
+
const mixedelem = [[], []];
|
|
1230
|
+
const x = elem1.map(d=>d.types); // extract types from elem1
|
|
1231
|
+
const y = elem2.map(d=>d.types); // extract types from elem
|
|
1232
|
+
const union = Array.from(getUnions(x,y)); // get the union of x and y
|
|
1233
|
+
mixedelem[0]['types'] = union; // store union in mixedelem array for elem1
|
|
1234
|
+
mixedelem[1]['types'] = union; // store union in mixedelem array for elem2
|
|
1235
|
+
return mixedelem // return mixedelem array
|
|
1236
|
+
}
|
|
1237
|
+
|
|
1238
|
+
// Combine elements and return a combined array containing counts, ranks, probs, and totalunique
|
|
1239
|
+
function combElems(elem1, elem2) {
|
|
1240
|
+
const mixedelem = buildMixedElems(elem1, elem2); // build mixed elements array
|
|
1241
|
+
const enum_list = [elem1, elem2]; // list containing elem1 and elem2
|
|
1242
|
+
|
|
1243
|
+
for (let j=0; j < enum_list.length; j++) {
|
|
1244
|
+
const enumlist_types = enum_list[j].map(d => d.types); // extract types from enum_list[j]
|
|
1245
|
+
const counts = new Array(mixedelem[j]['types'].length); // initialize counts array
|
|
1246
|
+
const probs = new Array(mixedelem[j]['types'].length); // initialize probs array
|
|
1247
|
+
|
|
1248
|
+
|
|
1249
|
+
// for each index in mixed elem[j], which is the union of both systems
|
|
1250
|
+
for (let i=0; i < mixedelem[j]['types'].length; i++) { // find the index of type mixedelem[j]['types'][i] in system 1 or 2
|
|
1251
|
+
// find the index of type mixedelem[j]['types'][i] in system 1 or 2
|
|
1252
|
+
let idx_type_enumlist_in_elem = enumlist_types.indexOf(mixedelem[j]['types'][i]);
|
|
1253
|
+
// if it exists, grabs counts and probs information else put a 0.
|
|
1254
|
+
counts[i] = idx_type_enumlist_in_elem === -1 ? 0 : enum_list[j][idx_type_enumlist_in_elem]["counts"];
|
|
1255
|
+
probs[i] = idx_type_enumlist_in_elem === -1 ? 0 : enum_list[j][idx_type_enumlist_in_elem]["probs"];
|
|
1256
|
+
}
|
|
1257
|
+
|
|
1258
|
+
|
|
1259
|
+
// store counts, ranks, probs, and totalunique in mixedelem array for elem1 or elem2
|
|
1260
|
+
mixedelem[j]['counts'] = counts;
|
|
1261
|
+
mixedelem[j]['ranks'] = tiedrank(mixedelem[j]['counts']);
|
|
1262
|
+
mixedelem[j]['probs'] = probs;
|
|
1263
|
+
mixedelem[j]['totalunique'] = getUnions().length;
|
|
1264
|
+
|
|
1265
|
+
}
|
|
1266
|
+
|
|
1267
|
+
return mixedelem // return mixedelem array
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1270
|
+
// helpers to wrangle data for the balance plot
|
|
1271
|
+
function balanceDat(elem1, elem2) {
|
|
1272
|
+
const types_1 = elem1.map(d => d.types);
|
|
1273
|
+
const types_2 = elem2.map(d => d.types);
|
|
1274
|
+
|
|
1275
|
+
const union_types = getUnions(types_1, types_2);
|
|
1276
|
+
const tot_types = types_1.length+types_2.length;
|
|
1277
|
+
|
|
1278
|
+
return [
|
|
1279
|
+
{ y_coord: "total count", frequency: +(types_2.length / tot_types).toFixed(3) },
|
|
1280
|
+
{ y_coord: "total count", frequency: -(types_1.length / tot_types).toFixed(3) },
|
|
1281
|
+
{ y_coord: "all names", frequency: +(types_2.length / union_types.size).toFixed(3) },
|
|
1282
|
+
{ y_coord: "all names", frequency: -(types_1.length / union_types.size).toFixed(3) },
|
|
1283
|
+
{ y_coord: "exclusive names", frequency: +(setdiff(types_2, types_1).size / types_2.length).toFixed(3) },
|
|
1284
|
+
{ y_coord: "exclusive names", frequency: -(setdiff(types_1, types_2).size / types_1.length).toFixed(3) }
|
|
1285
|
+
]
|
|
62
1286
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
1287
|
+
|
|
1288
|
+
// helper to wrangle the data for the wordshift plot
|
|
1289
|
+
function wordShift_dat(me, dat) {
|
|
1290
|
+
const out = [];
|
|
1291
|
+
for (let i=0; i < me[0]['types'].length; i++) {
|
|
1292
|
+
const rank_diff = me[0]['ranks'][i]-me[1]['ranks'][i];
|
|
1293
|
+
out.push({
|
|
1294
|
+
'type': `${me[0]['types'][i]} (${me[0]['ranks'][i]} ⇋ ${me[1]['ranks'][i]})` ,
|
|
1295
|
+
'rank_diff': rank_diff,
|
|
1296
|
+
'metric': rank_diff < 0 ? -dat.deltas[i] : dat.deltas[i],
|
|
1297
|
+
});
|
|
72
1298
|
}
|
|
73
|
-
|
|
74
|
-
|
|
1299
|
+
|
|
1300
|
+
return out.slice().sort((a, b) => descending(Math.abs(a.metric), Math.abs(b.metric)))
|
|
75
1301
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
return
|
|
1302
|
+
|
|
1303
|
+
// This function calculates the divergence between two arrays of inverse ranks
|
|
1304
|
+
// based on the specified alpha value. If alpha is equal to infinity, it returns
|
|
1305
|
+
// an array with the maximum of each element in inv_r1 and inv_r2. If alpha is
|
|
1306
|
+
// equal to 0, it returns an array with the log of the ratio of the maximum and
|
|
1307
|
+
// minimum of 1/inv_r1 and 1/inv_r2 for each element. Otherwise, it returns an
|
|
1308
|
+
// array with the absolute value of (alpha + 1)/alpha * (inv_r1^alpha - inv_r2^alpha)^(1/(alpha + 1))
|
|
1309
|
+
// for each element.
|
|
1310
|
+
|
|
1311
|
+
function divElems(inv_r1, inv_r2, alpha) {
|
|
1312
|
+
if (alpha === Infinity) {
|
|
1313
|
+
return inv_r1.map((d,i) => inv_r1[i] == inv_r2[i] ? 0 : Math.max(inv_r1[i], inv_r2[i]))
|
|
1314
|
+
} else if (alpha == 0) {
|
|
1315
|
+
const x_max = inv_r1.map((d,i) => Math.max(1 / inv_r1[i], 1 / inv_r2[i]));
|
|
1316
|
+
const x_min = inv_r1.map((d,i) => Math.min(1 / inv_r1[i], 1 / inv_r2[i]));
|
|
1317
|
+
return inv_r1.map((d,i) => Math.log10(x_max[i] / x_min[i]))
|
|
1318
|
+
} else {
|
|
1319
|
+
return inv_r1.map((d,i) => (alpha+1) / alpha * Math.abs(inv_r1[i]**alpha - inv_r2[i]**alpha)**(1. / (alpha+1)))
|
|
1320
|
+
}
|
|
1321
|
+
}
|
|
1322
|
+
|
|
1323
|
+
// This function calculates the normalization factor for the divergence between
|
|
1324
|
+
// two arrays of inverse ranks. It first extracts the counts from the mixedelements
|
|
1325
|
+
// parameter and finds the indices where the counts are greater than 0. It then
|
|
1326
|
+
// calculates the disjoint set for each array based on the number of non-zero
|
|
1327
|
+
// counts. If alpha is equal to infinity, it returns the sum of the elements in
|
|
1328
|
+
// inv_r1 and inv_r2 for the indices with non-zero counts. If alpha is equal to
|
|
1329
|
+
// 0, it returns the sum of the absolute value of the log of the ratio of each
|
|
1330
|
+
// element in inv_r1 and the disjoint set for inv_r2, and the absolute value of
|
|
1331
|
+
// the log of the ratio of each element in inv_r2 and the disjoint set for inv_r1.
|
|
1332
|
+
// Otherwise, it returns the sum of (alpha + 1)/alpha * (inv_r1^alpha - disjoint set^alpha)^(1/(alpha + 1))
|
|
1333
|
+
// for each element in inv_r1, and the same for inv_r2.
|
|
1334
|
+
|
|
1335
|
+
function norm_divElems(mixedelements, inv_r1, inv_r2, alpha) {
|
|
1336
|
+
const c1 = mixedelements[0]['counts'];
|
|
1337
|
+
const c2 = mixedelements[1]['counts'];
|
|
1338
|
+
|
|
1339
|
+
const indices1 = which(c1.map(d => d > 0));
|
|
1340
|
+
const indices2 = which(c2.map(d => d > 0));
|
|
1341
|
+
|
|
1342
|
+
const N1 = indices1.length;
|
|
1343
|
+
const N2 = indices2.length;
|
|
1344
|
+
|
|
1345
|
+
// This function calculates the disjoint set for a given array of inverse ranks
|
|
1346
|
+
// based on the number of non-zero counts in the array and the number of non-zero
|
|
1347
|
+
// counts in the other array. It returns 1/(number of non-zero counts in other array +
|
|
1348
|
+
// number of non-zero counts in this array/2)
|
|
1349
|
+
|
|
1350
|
+
function calc_disjoint(N1, N2) {
|
|
1351
|
+
return( 1 / (N2 + N1/2) )
|
|
1352
|
+
}
|
|
1353
|
+
|
|
1354
|
+
const inv_r1_disjoint = calc_disjoint(N1, N2);
|
|
1355
|
+
const inv_r2_disjoint = calc_disjoint(N2, N1);
|
|
1356
|
+
|
|
1357
|
+
if (alpha === Infinity) {
|
|
1358
|
+
|
|
1359
|
+
return sum(indices1.map((i) => inv_r1[i])) + sum(indices2.map((i) => inv_r2[i]))
|
|
1360
|
+
|
|
1361
|
+
} else if (alpha === 0) {
|
|
1362
|
+
const term1 = sum(
|
|
1363
|
+
indices1.map((i) => Math.abs(Math.log(inv_r1[i] / inv_r2_disjoint)))
|
|
1364
|
+
);
|
|
1365
|
+
const term2 = sum(
|
|
1366
|
+
indices2.map((i) => Math.abs(Math.log(inv_r2[i] / inv_r1_disjoint)))
|
|
1367
|
+
);
|
|
1368
|
+
return term1 + term2
|
|
1369
|
+
} else {
|
|
1370
|
+
const term1 = (alpha+1)/alpha * sum(
|
|
1371
|
+
indices1.map((i) => inv_r1[i]).map( d => (Math.abs(d**alpha) - inv_r2_disjoint**alpha)**(1./(alpha+1) ))
|
|
1372
|
+
);
|
|
1373
|
+
const term2 = (alpha+1)/alpha * sum(
|
|
1374
|
+
indices2.map((i) => inv_r2[i]).map(d => Math.abs(inv_r1_disjoint**alpha - d**alpha)**(1. / (alpha+1)))
|
|
1375
|
+
);
|
|
1376
|
+
return term1 + term2
|
|
88
1377
|
}
|
|
1378
|
+
}
|
|
1379
|
+
|
|
1380
|
+
// This function calculates the rank turbulence divergence for two arrays of mixed
|
|
1381
|
+
// elements, using the specified alpha value. It first calculates the arrays of
|
|
1382
|
+
// inverse ranks for each mixed element array and then calculates the divergence
|
|
1383
|
+
// and normalization factors using the divElems and norm_divElems functions. It
|
|
1384
|
+
// returns the divergence divided by the normalization.
|
|
1385
|
+
|
|
1386
|
+
function rank_turbulence_divergence(mixedelements, alpha) {
|
|
1387
|
+
|
|
1388
|
+
const inv_r1 = mixedelements[0]['ranks'].map(d => Math.pow(d, -1));
|
|
1389
|
+
const inv_r2 = mixedelements[1]['ranks'].map(d => Math.pow(d, -1));
|
|
1390
|
+
|
|
1391
|
+
const divergence_elements = divElems(inv_r1, inv_r2, alpha);
|
|
1392
|
+
const normalization = norm_divElems(mixedelements, inv_r1, inv_r2, alpha);
|
|
1393
|
+
|
|
1394
|
+
return { // the divergence used to wordshift dat to sort name in wordshift plot
|
|
1395
|
+
// is equal to the formula in the upperleft of the diamond plot. However
|
|
1396
|
+
// the formula is a proportionality and miss the normalization constant
|
|
1397
|
+
// shown here.
|
|
1398
|
+
// Example: for alpha = infinity, for the rank 1 names on both systems, the formula as written is equal to max(1/1, 1/former_rank) = 1/1 =1
|
|
1399
|
+
// this value of 1 is then divided by the normalization constant.
|
|
1400
|
+
// this constant of proportionality is the reason for the difference between the 1/1 that the written formula gives you
|
|
1401
|
+
// and the decimal value that wordshift_dat states and which is actuallly used to sort the types.
|
|
1402
|
+
'divergence_elements': divergence_elements.map(d => d / normalization),
|
|
1403
|
+
'normalization': normalization
|
|
89
1404
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
1405
|
+
}
|
|
1406
|
+
|
|
1407
|
+
const VOID = -1;
|
|
1408
|
+
const PRIMITIVE = 0;
|
|
1409
|
+
const ARRAY = 1;
|
|
1410
|
+
const OBJECT = 2;
|
|
1411
|
+
const DATE = 3;
|
|
1412
|
+
const REGEXP = 4;
|
|
1413
|
+
const MAP = 5;
|
|
1414
|
+
const SET = 6;
|
|
1415
|
+
const ERROR = 7;
|
|
1416
|
+
const BIGINT = 8;
|
|
1417
|
+
// export const SYMBOL = 9;
|
|
1418
|
+
|
|
1419
|
+
const env = typeof self === 'object' ? self : globalThis;
|
|
1420
|
+
|
|
1421
|
+
const deserializer = ($, _) => {
|
|
1422
|
+
const as = (out, index) => {
|
|
1423
|
+
$.set(index, out);
|
|
1424
|
+
return out;
|
|
1425
|
+
};
|
|
1426
|
+
|
|
1427
|
+
const unpair = index => {
|
|
1428
|
+
if ($.has(index))
|
|
1429
|
+
return $.get(index);
|
|
1430
|
+
|
|
1431
|
+
const [type, value] = _[index];
|
|
1432
|
+
switch (type) {
|
|
1433
|
+
case PRIMITIVE:
|
|
1434
|
+
case VOID:
|
|
1435
|
+
return as(value, index);
|
|
1436
|
+
case ARRAY: {
|
|
1437
|
+
const arr = as([], index);
|
|
1438
|
+
for (const index of value)
|
|
1439
|
+
arr.push(unpair(index));
|
|
1440
|
+
return arr;
|
|
1441
|
+
}
|
|
1442
|
+
case OBJECT: {
|
|
1443
|
+
const object = as({}, index);
|
|
1444
|
+
for (const [key, index] of value)
|
|
1445
|
+
object[unpair(key)] = unpair(index);
|
|
1446
|
+
return object;
|
|
96
1447
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
1448
|
+
case DATE:
|
|
1449
|
+
return as(new Date(value), index);
|
|
1450
|
+
case REGEXP: {
|
|
1451
|
+
const {source, flags} = value;
|
|
1452
|
+
return as(new RegExp(source, flags), index);
|
|
1453
|
+
}
|
|
1454
|
+
case MAP: {
|
|
1455
|
+
const map = as(new Map, index);
|
|
1456
|
+
for (const [key, index] of value)
|
|
1457
|
+
map.set(unpair(key), unpair(index));
|
|
1458
|
+
return map;
|
|
1459
|
+
}
|
|
1460
|
+
case SET: {
|
|
1461
|
+
const set = as(new Set, index);
|
|
1462
|
+
for (const index of value)
|
|
1463
|
+
set.add(unpair(index));
|
|
1464
|
+
return set;
|
|
1465
|
+
}
|
|
1466
|
+
case ERROR: {
|
|
1467
|
+
const {name, message} = value;
|
|
1468
|
+
return as(new env[name](message), index);
|
|
1469
|
+
}
|
|
1470
|
+
case BIGINT:
|
|
1471
|
+
return as(BigInt(value), index);
|
|
1472
|
+
case 'BigInt':
|
|
1473
|
+
return as(Object(BigInt(value)), index);
|
|
1474
|
+
case 'ArrayBuffer':
|
|
1475
|
+
return as(new Uint8Array(value).buffer, value);
|
|
1476
|
+
case 'DataView': {
|
|
1477
|
+
const { buffer } = new Uint8Array(value);
|
|
1478
|
+
return as(new DataView(buffer), value);
|
|
101
1479
|
}
|
|
102
1480
|
}
|
|
103
|
-
return
|
|
1481
|
+
return as(new env[type](value), index);
|
|
1482
|
+
};
|
|
1483
|
+
|
|
1484
|
+
return unpair;
|
|
1485
|
+
};
|
|
1486
|
+
|
|
1487
|
+
/**
|
|
1488
|
+
* @typedef {Array<string,any>} Record a type representation
|
|
1489
|
+
*/
|
|
1490
|
+
|
|
1491
|
+
/**
|
|
1492
|
+
* Returns a deserialized value from a serialized array of Records.
|
|
1493
|
+
* @param {Record[]} serialized a previously serialized value.
|
|
1494
|
+
* @returns {any}
|
|
1495
|
+
*/
|
|
1496
|
+
const deserialize = serialized => deserializer(new Map, serialized)(0);
|
|
1497
|
+
|
|
1498
|
+
const EMPTY = '';
|
|
1499
|
+
|
|
1500
|
+
const {toString} = {};
|
|
1501
|
+
const {keys} = Object;
|
|
1502
|
+
|
|
1503
|
+
const typeOf = value => {
|
|
1504
|
+
const type = typeof value;
|
|
1505
|
+
if (type !== 'object' || !value)
|
|
1506
|
+
return [PRIMITIVE, type];
|
|
1507
|
+
|
|
1508
|
+
const asString = toString.call(value).slice(8, -1);
|
|
1509
|
+
switch (asString) {
|
|
1510
|
+
case 'Array':
|
|
1511
|
+
return [ARRAY, EMPTY];
|
|
1512
|
+
case 'Object':
|
|
1513
|
+
return [OBJECT, EMPTY];
|
|
1514
|
+
case 'Date':
|
|
1515
|
+
return [DATE, EMPTY];
|
|
1516
|
+
case 'RegExp':
|
|
1517
|
+
return [REGEXP, EMPTY];
|
|
1518
|
+
case 'Map':
|
|
1519
|
+
return [MAP, EMPTY];
|
|
1520
|
+
case 'Set':
|
|
1521
|
+
return [SET, EMPTY];
|
|
1522
|
+
case 'DataView':
|
|
1523
|
+
return [ARRAY, asString];
|
|
104
1524
|
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
1525
|
+
|
|
1526
|
+
if (asString.includes('Array'))
|
|
1527
|
+
return [ARRAY, asString];
|
|
1528
|
+
|
|
1529
|
+
if (asString.includes('Error'))
|
|
1530
|
+
return [ERROR, asString];
|
|
1531
|
+
|
|
1532
|
+
return [OBJECT, asString];
|
|
1533
|
+
};
|
|
1534
|
+
|
|
1535
|
+
const shouldSkip = ([TYPE, type]) => (
|
|
1536
|
+
TYPE === PRIMITIVE &&
|
|
1537
|
+
(type === 'function' || type === 'symbol')
|
|
1538
|
+
);
|
|
1539
|
+
|
|
1540
|
+
const serializer = (strict, json, $, _) => {
|
|
1541
|
+
|
|
1542
|
+
const as = (out, value) => {
|
|
1543
|
+
const index = _.push(out) - 1;
|
|
1544
|
+
$.set(value, index);
|
|
1545
|
+
return index;
|
|
1546
|
+
};
|
|
1547
|
+
|
|
1548
|
+
const pair = value => {
|
|
1549
|
+
if ($.has(value))
|
|
1550
|
+
return $.get(value);
|
|
1551
|
+
|
|
1552
|
+
let [TYPE, type] = typeOf(value);
|
|
1553
|
+
switch (TYPE) {
|
|
1554
|
+
case PRIMITIVE: {
|
|
1555
|
+
let entry = value;
|
|
1556
|
+
switch (type) {
|
|
1557
|
+
case 'bigint':
|
|
1558
|
+
TYPE = BIGINT;
|
|
1559
|
+
entry = value.toString();
|
|
1560
|
+
break;
|
|
1561
|
+
case 'function':
|
|
1562
|
+
case 'symbol':
|
|
1563
|
+
if (strict)
|
|
1564
|
+
throw new TypeError('unable to serialize ' + type);
|
|
1565
|
+
entry = null;
|
|
1566
|
+
break;
|
|
1567
|
+
case 'undefined':
|
|
1568
|
+
return as([VOID], value);
|
|
1569
|
+
}
|
|
1570
|
+
return as([TYPE, entry], value);
|
|
1571
|
+
}
|
|
1572
|
+
case ARRAY: {
|
|
1573
|
+
if (type) {
|
|
1574
|
+
let spread = value;
|
|
1575
|
+
if (type === 'DataView') {
|
|
1576
|
+
spread = new Uint8Array(value.buffer);
|
|
1577
|
+
}
|
|
1578
|
+
else if (type === 'ArrayBuffer') {
|
|
1579
|
+
spread = new Uint8Array(value);
|
|
119
1580
|
}
|
|
1581
|
+
return as([type, [...spread]], value);
|
|
120
1582
|
}
|
|
121
|
-
|
|
122
|
-
|
|
1583
|
+
|
|
1584
|
+
const arr = [];
|
|
1585
|
+
const index = as([TYPE, arr], value);
|
|
1586
|
+
for (const entry of value)
|
|
1587
|
+
arr.push(pair(entry));
|
|
1588
|
+
return index;
|
|
1589
|
+
}
|
|
1590
|
+
case OBJECT: {
|
|
1591
|
+
if (type) {
|
|
1592
|
+
switch (type) {
|
|
1593
|
+
case 'BigInt':
|
|
1594
|
+
return as([type, value.toString()], value);
|
|
1595
|
+
case 'Boolean':
|
|
1596
|
+
case 'Number':
|
|
1597
|
+
case 'String':
|
|
1598
|
+
return as([type, value.valueOf()], value);
|
|
1599
|
+
}
|
|
123
1600
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
const scale = d3.scaleLinear().domain([0, Ncontours + 1]).range([1, tmpr1.length]);
|
|
134
|
-
const contour_indices = d3.range(Ncontours + 2).map((i) => Math.round(scale(i)));
|
|
135
|
-
const grid = make_grid(Ninset, tmpr1, tmpr2, alpha2, rtd2);
|
|
136
|
-
const indices = contour_indices.slice(1, -1);
|
|
137
|
-
const lastRow = grid[grid.length - 1];
|
|
138
|
-
const heights = indices.map((index) => lastRow[index]);
|
|
139
|
-
const logTmpr = tmpr1.map(Math.log10);
|
|
140
|
-
const contourGenerator = d3.contours().size([logTmpr.length, logTmpr.length]).thresholds(heights);
|
|
141
|
-
const flatDeltamatrix = grid.flat();
|
|
142
|
-
const tmpcontours = contourGenerator(flatDeltamatrix);
|
|
143
|
-
return filter_contours(tmpcontours, Ninset, maxlog102);
|
|
144
|
-
}
|
|
145
|
-
let mycontours = get_contours(alpha, maxlog10, rtd);
|
|
146
|
-
const x = d3.scaleLinear([0, maxlog10], [0, DiamondInnerHeight]);
|
|
147
|
-
const y = d3.scaleLinear([maxlog10, 0], [DiamondInnerHeight, 0]);
|
|
148
|
-
const pathData = d3.line().x((d, i) => x(d[0])).y((d, i) => y(d[1]));
|
|
149
|
-
const each_array = $.ensure_array_like(mycontours);
|
|
150
|
-
$$payload.out += `<g class="contours"><!--[-->`;
|
|
151
|
-
for (let index = 0, $$length = each_array.length; index < $$length; index++) {
|
|
152
|
-
let contour = each_array[index];
|
|
153
|
-
$$payload.out += `<path fill="none" stroke="grey"${$.attr("d", pathData(contour))} stroke-width="0.9" stroke-opacity="0.9"></path>`;
|
|
154
|
-
}
|
|
155
|
-
$$payload.out += `<!--]--></g>`;
|
|
156
|
-
$.pop();
|
|
157
|
-
}
|
|
158
|
-
function Diamond($$payload, $$props) {
|
|
159
|
-
$.push();
|
|
160
|
-
let {
|
|
161
|
-
diamond_count,
|
|
162
|
-
diamond_dat,
|
|
163
|
-
margin,
|
|
164
|
-
DiamondInnerHeight,
|
|
165
|
-
trueDiamondHeight,
|
|
166
|
-
alpha,
|
|
167
|
-
maxlog10,
|
|
168
|
-
rtd,
|
|
169
|
-
title
|
|
170
|
-
} = $$props;
|
|
171
|
-
function get_relevant_types(diamond_dat2) {
|
|
172
|
-
const ncells2 = 60;
|
|
173
|
-
const bin_size = 1.5;
|
|
174
|
-
const cummulative_bin = d3.range(0, ncells2, bin_size);
|
|
175
|
-
const relevant_types2 = [];
|
|
176
|
-
for (let sys of ["right", "left"]) {
|
|
177
|
-
for (let i = 1; i < cummulative_bin.length; i++) {
|
|
178
|
-
const filtered_dat = diamond_dat2.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]);
|
|
179
|
-
if (filtered_dat.length > 0) {
|
|
180
|
-
const cos_dists = filtered_dat.map((d) => d.cos_dist);
|
|
181
|
-
const max_dist = cos_dists.reduce((a, b) => {
|
|
182
|
-
return Math.max(a, b);
|
|
183
|
-
});
|
|
184
|
-
const max_dist_idx = cos_dists.indexOf(max_dist);
|
|
185
|
-
const types = filtered_dat[max_dist_idx]["types"].split(",");
|
|
186
|
-
const name = types[Math.floor(Math.random() * types.length)];
|
|
187
|
-
relevant_types2.push(name);
|
|
1601
|
+
|
|
1602
|
+
if (json && ('toJSON' in value))
|
|
1603
|
+
return pair(value.toJSON());
|
|
1604
|
+
|
|
1605
|
+
const entries = [];
|
|
1606
|
+
const index = as([TYPE, entries], value);
|
|
1607
|
+
for (const key of keys(value)) {
|
|
1608
|
+
if (strict || !shouldSkip(typeOf(value[key])))
|
|
1609
|
+
entries.push([pair(key), pair(value[key])]);
|
|
188
1610
|
}
|
|
1611
|
+
return index;
|
|
1612
|
+
}
|
|
1613
|
+
case DATE:
|
|
1614
|
+
return as([TYPE, value.toISOString()], value);
|
|
1615
|
+
case REGEXP: {
|
|
1616
|
+
const {source, flags} = value;
|
|
1617
|
+
return as([TYPE, {source, flags}], value);
|
|
1618
|
+
}
|
|
1619
|
+
case MAP: {
|
|
1620
|
+
const entries = [];
|
|
1621
|
+
const index = as([TYPE, entries], value);
|
|
1622
|
+
for (const [key, entry] of value) {
|
|
1623
|
+
if (strict || !(shouldSkip(typeOf(key)) || shouldSkip(typeOf(entry))))
|
|
1624
|
+
entries.push([pair(key), pair(entry)]);
|
|
1625
|
+
}
|
|
1626
|
+
return index;
|
|
1627
|
+
}
|
|
1628
|
+
case SET: {
|
|
1629
|
+
const entries = [];
|
|
1630
|
+
const index = as([TYPE, entries], value);
|
|
1631
|
+
for (const entry of value) {
|
|
1632
|
+
if (strict || !shouldSkip(typeOf(entry)))
|
|
1633
|
+
entries.push(pair(entry));
|
|
1634
|
+
}
|
|
1635
|
+
return index;
|
|
189
1636
|
}
|
|
190
1637
|
}
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
return Array.from(arr1, (x) => {
|
|
195
|
-
return arr2.indexOf(x) == -1 ? false : true;
|
|
196
|
-
});
|
|
197
|
-
}
|
|
198
|
-
let relevant_types = get_relevant_types(diamond_dat);
|
|
199
|
-
let max_rank_raw = d3.range(d3.max(diamond_count, (d) => d.x1));
|
|
200
|
-
let max_rank = d3.max(diamond_dat, (d) => d.rank_L[1]);
|
|
201
|
-
let rounded_max_rank = 10 ** Math.ceil(Math.max(Math.log10(max_rank)));
|
|
202
|
-
let ncells = d3.max(max_rank_raw);
|
|
203
|
-
let xyDomain = [1, rounded_max_rank];
|
|
204
|
-
let linScale = d3.scaleLinear().domain([0, ncells - 1]).range([0, DiamondInnerHeight]);
|
|
205
|
-
let wxy = d3.scaleBand().domain(max_rank_raw).range([0, DiamondInnerHeight]);
|
|
206
|
-
let logScale = d3.scaleLog().domain(xyDomain).range([0, DiamondInnerHeight]).nice();
|
|
207
|
-
let xy = d3.scaleBand().domain(max_rank_raw).range([0, trueDiamondHeight]);
|
|
208
|
-
let color_scale = d3.scaleSequentialLog().domain([rounded_max_rank, 1]).interpolator(d3.interpolateInferno);
|
|
209
|
-
let blue_triangle = [
|
|
210
|
-
[DiamondInnerHeight, DiamondInnerHeight],
|
|
211
|
-
[0, 0],
|
|
212
|
-
[0, DiamondInnerHeight]
|
|
213
|
-
].join(" ");
|
|
214
|
-
let grey_triangle = [
|
|
215
|
-
[DiamondInnerHeight, DiamondInnerHeight],
|
|
216
|
-
[0, 0],
|
|
217
|
-
[DiamondInnerHeight, 0]
|
|
218
|
-
].join(" ");
|
|
219
|
-
function filter_labs(d, relevant_types2) {
|
|
220
|
-
return rin(relevant_types2, d.types.split(",")).some((x) => x === true);
|
|
221
|
-
}
|
|
222
|
-
const each_array = $.ensure_array_like(diamond_dat);
|
|
223
|
-
const each_array_1 = $.ensure_array_like(diamond_dat.filter((d) => filter_labs(d, relevant_types)));
|
|
224
|
-
$$payload.out += `<g class="diamond-chart"${$.attr("transform", `translate(360, 0) scale (-1,1) rotate(45) translate(${$.stringify(margin.inner / 2)}, ${$.stringify(margin.inner / 2)})`)}><polygon${$.attr("points", blue_triangle)} fill="#89CFF0" fill-opacity="0.2" stroke="black" stroke-width="0.5"></polygon><polygon${$.attr("points", grey_triangle)} fill="grey" fill-opacity="0.2" stroke="black" stroke-width="0.5"></polygon>`;
|
|
225
|
-
AxisX($$payload, {
|
|
226
|
-
height: DiamondInnerHeight,
|
|
227
|
-
scale: logScale,
|
|
228
|
-
title
|
|
229
|
-
});
|
|
230
|
-
$$payload.out += `<!---->`;
|
|
231
|
-
AxisY($$payload, {
|
|
232
|
-
height: DiamondInnerHeight,
|
|
233
|
-
scale: logScale,
|
|
234
|
-
title
|
|
235
|
-
});
|
|
236
|
-
$$payload.out += `<!---->`;
|
|
237
|
-
Grid($$payload, {
|
|
238
|
-
height: DiamondInnerHeight,
|
|
239
|
-
wxy,
|
|
240
|
-
ncells,
|
|
241
|
-
scale: linScale
|
|
242
|
-
});
|
|
243
|
-
$$payload.out += `<!----><!--[-->`;
|
|
244
|
-
for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
|
|
245
|
-
let d = each_array[$$index];
|
|
246
|
-
$$payload.out += `<rect${$.attr("x", xy(d.x1))}${$.attr("y", xy(d.y1))}${$.attr("width", xy.bandwidth())}${$.attr("height", xy.bandwidth())}${$.attr("fill", color_scale(d.value))}${$.attr("opacity", d.value === null ? 0 : 1)} stroke="black" stroke-width="0.2"></rect>`;
|
|
247
|
-
}
|
|
248
|
-
$$payload.out += `<!--]--><!--[-->`;
|
|
249
|
-
for (let $$index_1 = 0, $$length = each_array_1.length; $$index_1 < $$length; $$index_1++) {
|
|
250
|
-
let d = each_array_1[$$index_1];
|
|
251
|
-
$$payload.out += `<g class="diamond-lab"${$.attr("transform", `
|
|
252
|
-
scale(1,-1)
|
|
253
|
-
rotate(-90)
|
|
254
|
-
rotate(-45, ${$.stringify(xy(d.x1))}, ${$.stringify(xy(d.y1))})
|
|
255
|
-
translate(${$.stringify(d.which_sys === "right" ? xy(Math.sqrt(d.cos_dist)) * 1.5 : -xy(Math.sqrt(d.cos_dist)) * 1.5)}, 0)
|
|
256
|
-
`)}><text${$.attr("x", xy(d.x1))}${$.attr("y", Number.isInteger(d.coord_on_diag) ? xy(d.y1) : xy(d.y1) - 1)} dy="20" font-size="10"${$.attr("text-anchor", d.x1 - d.y1 <= 0 ? "start" : "end")}>${$.escape(d.types.split(",")[0])}</text></g>`;
|
|
257
|
-
}
|
|
258
|
-
$$payload.out += `<!--]-->`;
|
|
259
|
-
Contours($$payload, { alpha, maxlog10, rtd, DiamondInnerHeight });
|
|
260
|
-
$$payload.out += `<!----></g>`;
|
|
261
|
-
$.pop();
|
|
262
|
-
}
|
|
263
|
-
function Wordshift($$payload, $$props) {
|
|
264
|
-
$.push();
|
|
265
|
-
let { barData, DashboardHeight, DashboardWidth } = $$props;
|
|
266
|
-
let margin = { top: 80, left: 140, right: 50, bottom: 10 };
|
|
267
|
-
let width = 640;
|
|
268
|
-
let yPadding = 0.2;
|
|
269
|
-
let Y = d3.map(barData, (d) => d.type);
|
|
270
|
-
let max_shift = d3.max(barData, (d) => Math.abs(d.metric)) * 1.5;
|
|
271
|
-
let xDomain = [-max_shift, max_shift];
|
|
272
|
-
let yDomain = new d3.InternSet(Y);
|
|
273
|
-
let xRange = [
|
|
274
|
-
DashboardWidth - width + margin.left,
|
|
275
|
-
DashboardWidth - margin.right
|
|
276
|
-
];
|
|
277
|
-
let yRange = [margin.top, DashboardHeight - margin.bottom];
|
|
278
|
-
let xScale = d3.scaleLinear().domain(xDomain).range(xRange);
|
|
279
|
-
let yScale = d3.scaleBand(yDomain, yRange).padding(yPadding);
|
|
280
|
-
let xTicks = xScale.ticks(width / 80);
|
|
281
|
-
const colors = ["lightgrey", "lightblue"];
|
|
282
|
-
const each_array = $.ensure_array_like(xTicks);
|
|
283
|
-
const each_array_1 = $.ensure_array_like(barData);
|
|
284
|
-
$$payload.out += `<g class="barChart-container svelte-37sv8o"><g class="axis x"${$.attr("transform", `translate(0, ${$.stringify(margin.top)})`)}><!--[-->`;
|
|
285
|
-
for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
|
|
286
|
-
let tick = each_array[$$index];
|
|
287
|
-
$$payload.out += `<g class="tick"><line${$.attr("x1", xScale(tick))} y1="0"${$.attr("x2", xScale(tick))}${$.attr("y2", DashboardHeight - margin.top - margin.bottom)} stroke="hsla(212, 10%, 53%, 1)" stroke-opacity="0.2">${$.escape(tick)}</line><text${$.attr("x", xScale(tick))} y="-12" font-size="0.8em">${$.escape(tick * 100)}%</text></g>`;
|
|
288
|
-
}
|
|
289
|
-
$$payload.out += `<!--]--></g><!--[-->`;
|
|
290
|
-
for (let i = 0, $$length = each_array_1.length; i < $$length; i++) {
|
|
291
|
-
let d = each_array_1[i];
|
|
292
|
-
$$payload.out += `<rect${$.attr("x", Math.min(xScale(0), xScale(d.metric)))}${$.attr("y", yScale(d.type))}${$.attr("fill", colors[d.metric > 0 ? colors.length - 1 : 0])}${$.attr("width", Math.abs(xScale(d.metric) - xScale(0)))}${$.attr("height", yScale.bandwidth())}></rect><text${$.attr("x", Math.min(xScale(0), xScale(d.metric)))}${$.attr("y", yScale(d.type))} dy="14" font-size="0.7em">${$.escape(d.type)}</text>`;
|
|
293
|
-
}
|
|
294
|
-
$$payload.out += `<!--]--></g>`;
|
|
295
|
-
$.pop();
|
|
296
|
-
}
|
|
297
|
-
function DivergingBarChart($$payload, $$props) {
|
|
298
|
-
$.push();
|
|
299
|
-
let {
|
|
300
|
-
test_elem_1,
|
|
301
|
-
test_elem_2,
|
|
302
|
-
DiamondHeight,
|
|
303
|
-
DiamondWidth
|
|
304
|
-
} = $$props;
|
|
305
|
-
const setdiff = (x, y) => {
|
|
306
|
-
let a = new Set(x);
|
|
307
|
-
let b = new Set(y);
|
|
308
|
-
return new Set([...a].filter((x2) => !b.has(x2)));
|
|
309
|
-
};
|
|
310
|
-
const union = (x, y) => {
|
|
311
|
-
let a = new Set(x);
|
|
312
|
-
let b = new Set(y);
|
|
313
|
-
return /* @__PURE__ */ new Set([...a, ...b]);
|
|
1638
|
+
|
|
1639
|
+
const {message} = value;
|
|
1640
|
+
return as([TYPE, {name: type, message}], value);
|
|
314
1641
|
};
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
$$payload.out += `<rect${$.attr("x", Math.min(xScale(0), xScale(d.frequency)))}${$.attr("y", yScale(d.y_coord))}${$.attr("fill", colors[X[i] > 0 ? colors.length - 1 : 0])}${$.attr("width", Math.abs(xScale(d.frequency) - xScale(0)))}${$.attr("height", yScale.bandwidth())}></rect><text${$.attr("x", xScale(X[i]) + Math.sign(X[i] - 0) * 4)}${$.attr("y", yScale(Y[i]) + yScale.bandwidth() / 2)} opacity="0.5" dy="0.35em" font-size="10"${$.attr("text-anchor", d.frequency < 0 ? "end" : "start")}>${$.escape(format(Math.abs(d.frequency)))}</text>`;
|
|
366
|
-
}
|
|
367
|
-
$$payload.out += `<!--]--><!--[-->`;
|
|
368
|
-
for (let i = 0, $$length = each_array_1.length; i < $$length; i++) {
|
|
369
|
-
let text = each_array_1[i];
|
|
370
|
-
$$payload.out += `<g class="diverging-ticks"><text${$.attr("x", xScale(0))}${$.attr("y", yScale(text) + yScale.bandwidth() / 2)} dy="-.9em" dx="-3em" font-size="10">${$.escape(text)}</text></g>`;
|
|
371
|
-
}
|
|
372
|
-
$$payload.out += `<!--]--></g>`;
|
|
373
|
-
$.pop();
|
|
374
|
-
}
|
|
375
|
-
function Legend($$payload, $$props) {
|
|
376
|
-
$.push();
|
|
377
|
-
let { diamond_dat, DiamondHeight } = $$props;
|
|
378
|
-
const N_CATEGO = 20;
|
|
379
|
-
const myramp = range$1(N_CATEGO).map((i) => rgb(interpolateInferno(i / (N_CATEGO - 1))).hex());
|
|
380
|
-
const color = scaleOrdinal(range$1(N_CATEGO), myramp);
|
|
381
|
-
let height = 370;
|
|
382
|
-
const margin = { right: 40, top: 65, left: 10 };
|
|
383
|
-
let innerHeight = height - margin.top - margin.right;
|
|
384
|
-
let max_rank = max(diamond_dat, (d) => d.rank_L[1]);
|
|
385
|
-
let y = scaleBand().domain(color.domain().reverse()).rangeRound([0, innerHeight]);
|
|
386
|
-
let logY = scaleLog().domain([
|
|
387
|
-
1,
|
|
388
|
-
10 ** Math.ceil(Math.max(Math.log10(max_rank)) - 1)
|
|
389
|
-
]).rangeRound([0, innerHeight]).nice();
|
|
390
|
-
let logFormat10 = logY.tickFormat();
|
|
391
|
-
let yTicks = logY.ticks();
|
|
392
|
-
const each_array = $.ensure_array_like(color.domain());
|
|
393
|
-
const each_array_1 = $.ensure_array_like(yTicks);
|
|
394
|
-
$$payload.out += `<g class="legend-container"${$.attr("transform", `translate(${$.stringify(margin.left)}, ${$.stringify(DiamondHeight - margin.top)})`)}><!--[-->`;
|
|
395
|
-
for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
|
|
396
|
-
let d = each_array[$$index];
|
|
397
|
-
$$payload.out += `<rect${$.attr("x", 0)}${$.attr("y", y(d))}${$.attr("width", 14)}${$.attr("height", 13)}${$.attr("fill", color(d))} stroke="whitesmoke" stroke-width="1"></rect>`;
|
|
1642
|
+
|
|
1643
|
+
return pair;
|
|
1644
|
+
};
|
|
1645
|
+
|
|
1646
|
+
/**
|
|
1647
|
+
* @typedef {Array<string,any>} Record a type representation
|
|
1648
|
+
*/
|
|
1649
|
+
|
|
1650
|
+
/**
|
|
1651
|
+
* Returns an array of serialized Records.
|
|
1652
|
+
* @param {any} value a serializable value.
|
|
1653
|
+
* @param {{json?: boolean, lossy?: boolean}?} options an object with a `lossy` or `json` property that,
|
|
1654
|
+
* if `true`, will not throw errors on incompatible types, and behave more
|
|
1655
|
+
* like JSON stringify would behave. Symbol and Function will be discarded.
|
|
1656
|
+
* @returns {Record[]}
|
|
1657
|
+
*/
|
|
1658
|
+
const serialize = (value, {json, lossy} = {}) => {
|
|
1659
|
+
const _ = [];
|
|
1660
|
+
return serializer(!(json || lossy), !!json, new Map, _)(value), _;
|
|
1661
|
+
};
|
|
1662
|
+
|
|
1663
|
+
/**
|
|
1664
|
+
* @typedef {Array<string,any>} Record a type representation
|
|
1665
|
+
*/
|
|
1666
|
+
|
|
1667
|
+
/**
|
|
1668
|
+
* Returns an array of serialized Records.
|
|
1669
|
+
* @param {any} any a serializable value.
|
|
1670
|
+
* @param {{transfer?: any[], json?: boolean, lossy?: boolean}?} options an object with
|
|
1671
|
+
* a transfer option (ignored when polyfilled) and/or non standard fields that
|
|
1672
|
+
* fallback to the polyfill if present.
|
|
1673
|
+
* @returns {Record[]}
|
|
1674
|
+
*/
|
|
1675
|
+
const structuredClone$1 = typeof structuredClone === "function" ?
|
|
1676
|
+
/* c8 ignore start */
|
|
1677
|
+
(any, options) => (
|
|
1678
|
+
options && ('json' in options || 'lossy' in options) ?
|
|
1679
|
+
deserialize(serialize(any, options)) : structuredClone(any)
|
|
1680
|
+
) :
|
|
1681
|
+
(any, options) => deserialize(serialize(any, options));
|
|
1682
|
+
|
|
1683
|
+
function rank2coord(rank) { return Math.floor(Math.log10(rank) / (1/15)) }
|
|
1684
|
+
|
|
1685
|
+
// Augment information already in `me` class with coordinates.
|
|
1686
|
+
function diamond_counts(mixedelements) {
|
|
1687
|
+
|
|
1688
|
+
let maxlog10 = rank_maxlog10(mixedelements); // max of values of me[system]['rank'] in logspace
|
|
1689
|
+
|
|
1690
|
+
if (maxlog10 < 1) {
|
|
1691
|
+
maxlog10 = 1;
|
|
398
1692
|
}
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
1693
|
+
|
|
1694
|
+
const CELL_LENGTH = 1/15;
|
|
1695
|
+
const Ncells = Math.floor(maxlog10/CELL_LENGTH) + 1;
|
|
1696
|
+
|
|
1697
|
+
// me = mixed elements which is of the form:
|
|
1698
|
+
// [array_from_system_L, array_from_system_R]
|
|
1699
|
+
// where each array is of the form [types:{types}, counts:{counts}, ranks:{ranks}, probs:{probs}, totalunique]
|
|
1700
|
+
// where types is in the order [rank1TypeFromL, rank1TypeFromR, ... rankMaxTypeFromL, rankMaxTypeFromR] and if there is a tie it goes ... ranknTypeFromL, ranknTypeFromR_1, ranknTypeFromR_2, ranknplus1TypeFromL ... Example 1880-2015 charlie and clarence tie from left
|
|
1701
|
+
// counts, ranks, and probs are correct corresponding to the types
|
|
1702
|
+
const x1s = mixedelements[0]['ranks'].map(r => rank2coord(r)); // Math.floor(Math.log10(rank) / (1/15))
|
|
1703
|
+
const y1s = mixedelements[1]['ranks'].map(r => rank2coord(r));
|
|
1704
|
+
|
|
1705
|
+
// all the combination of coords that exists. There are many duplicated coords.
|
|
1706
|
+
const existing_coords = Array.from(mixedelements[0]['ranks'], (d,i) => { return `(${x1s[i]}, ${y1s[i]})` }); // for i in range(len(me[0]['ranks'])), existing_coords.append('x1s[i], y1s[i]'). or alternatively existing_coords = [str(pair) for pair in zip(x1s, y1s)]
|
|
1707
|
+
// note we make this a tring so that indexOf works later. In python we would use a 2-tuple
|
|
1708
|
+
|
|
1709
|
+
// return existing_coords
|
|
1710
|
+
|
|
1711
|
+
const out = [];
|
|
1712
|
+
// iterate through each cell
|
|
1713
|
+
for (var i=0; i < Ncells; i++) { // Ncells is the length of the square matrix (note 1-d length not total number of cells)
|
|
1714
|
+
for (var j=0; j < Ncells; j++) {
|
|
1715
|
+
|
|
1716
|
+
// Does coords (i,j) are in existing_coords?
|
|
1717
|
+
if ( existing_coords.indexOf(`(${i}, ${j})`) === -1) {
|
|
1718
|
+
out.push({ types: "", x1: i, y1: j, rank1: "", rank2: "" }); // if it doesnt exist, thats a blank cell, make the data there blank
|
|
1719
|
+
} else { //if that coordinate is full of data
|
|
1720
|
+
const indices_coords_in_exist_coords = which(rin(existing_coords, `(${i}, ${j})`)); //rin(arr1, arr2) = [foo is in arr2 for foo in arr1]. rin([3, 4, 5], [3]) = [true, false, false], then the which is returning the indices of the elements which are true. So in the end this is getting all the indices where '${i}, ${j})' appears in existing_coords. When there are ties, the same coordinate appears multiple times in a row in exisiting_coords and so indices_coords_in_exist_coords will be an array with multiple indices
|
|
1721
|
+
|
|
1722
|
+
for (let z=0; z < indices_coords_in_exist_coords.length; z++ ) {
|
|
1723
|
+
out.push({
|
|
1724
|
+
types: mixedelements[0]['types'][indices_coords_in_exist_coords[z]],
|
|
1725
|
+
x1: i,
|
|
1726
|
+
y1: j,
|
|
1727
|
+
rank1: mixedelements[0]['ranks'][indices_coords_in_exist_coords[z]],
|
|
1728
|
+
rank2: mixedelements[1]['ranks'][indices_coords_in_exist_coords[z]]
|
|
1729
|
+
});
|
|
1730
|
+
}
|
|
1731
|
+
}
|
|
408
1732
|
}
|
|
409
|
-
$$payload.out += `<!--]-->`;
|
|
410
1733
|
}
|
|
411
|
-
|
|
412
|
-
|
|
1734
|
+
// group data by unique coordinates
|
|
1735
|
+
const agg_dat = group(out, d => `${d.x1}, ${d.y1}`);
|
|
1736
|
+
|
|
1737
|
+
return Array.from(agg_dat , ([ key, value ]) => {
|
|
1738
|
+
const x1 = +key.split(", ")[1]; // 2
|
|
1739
|
+
const y1 = +key.split(", ")[0]; // 7
|
|
1740
|
+
return {
|
|
1741
|
+
x1: x1,
|
|
1742
|
+
y1: y1,
|
|
1743
|
+
coord_on_diag: (y1+x1)/2,
|
|
1744
|
+
cos_dist: (x1-y1)**2,
|
|
1745
|
+
rank: value.map(d => d.types)[0] === "" ? "" : value.map(d => `(${d.rank1}, ${d.rank2})`)[0],
|
|
1746
|
+
rank_L: value.map(d => d.types)[0] === "" ? "" : extent$1(value.map(d => d.rank1)),
|
|
1747
|
+
rank_R: value.map(d => d.types)[0] === "" ? "" : extent$1(value.map(d => d.rank2)),
|
|
1748
|
+
value: value.map(d => d.types)[0] === "" ? 0 : value.length,
|
|
1749
|
+
types: value.map(d => d.types).join(', '),
|
|
1750
|
+
which_sys: x1 - y1 <= 0 ? "right" : "left"
|
|
1751
|
+
}
|
|
1752
|
+
})
|
|
413
1753
|
}
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
...restProps
|
|
447
|
-
},
|
|
448
|
-
"svelte-n6o6ey"
|
|
449
|
-
)}><svg id="allotaxonometer-svg"${$.attr("height", height)}${$.attr("width", width)} class="svelte-n6o6ey">`;
|
|
450
|
-
if (showDiamond) {
|
|
451
|
-
$$payload.out += "<!--[-->";
|
|
452
|
-
Diamond($$payload, {
|
|
453
|
-
diamond_count,
|
|
454
|
-
diamond_dat,
|
|
455
|
-
DiamondInnerHeight,
|
|
456
|
-
margin,
|
|
457
|
-
trueDiamondHeight,
|
|
458
|
-
alpha,
|
|
459
|
-
maxlog10,
|
|
460
|
-
rtd,
|
|
461
|
-
title
|
|
462
|
-
});
|
|
463
|
-
} else {
|
|
464
|
-
$$payload.out += "<!--[!-->";
|
|
465
|
-
}
|
|
466
|
-
$$payload.out += `<!--]-->`;
|
|
467
|
-
if (showWordshift) {
|
|
468
|
-
$$payload.out += "<!--[-->";
|
|
469
|
-
Wordshift($$payload, {
|
|
470
|
-
barData,
|
|
471
|
-
DashboardHeight: height,
|
|
472
|
-
DashboardWidth: width
|
|
473
|
-
});
|
|
474
|
-
} else {
|
|
475
|
-
$$payload.out += "<!--[!-->";
|
|
476
|
-
}
|
|
477
|
-
$$payload.out += `<!--]-->`;
|
|
478
|
-
if (showDivergingBar) {
|
|
479
|
-
$$payload.out += "<!--[-->";
|
|
480
|
-
DivergingBarChart($$payload, {
|
|
481
|
-
test_elem_1,
|
|
482
|
-
test_elem_2,
|
|
483
|
-
DiamondHeight,
|
|
484
|
-
DiamondWidth
|
|
485
|
-
});
|
|
486
|
-
} else {
|
|
487
|
-
$$payload.out += "<!--[!-->";
|
|
488
|
-
}
|
|
489
|
-
$$payload.out += `<!--]-->`;
|
|
490
|
-
if (showLegend) {
|
|
491
|
-
$$payload.out += "<!--[-->";
|
|
492
|
-
Legend($$payload, { diamond_dat, DiamondHeight });
|
|
493
|
-
} else {
|
|
494
|
-
$$payload.out += "<!--[!-->";
|
|
495
|
-
}
|
|
496
|
-
$$payload.out += `<!--]--></svg></div>`;
|
|
1754
|
+
|
|
1755
|
+
|
|
1756
|
+
// we expect wordshift to be of the form { divergence_elements: [ length of type ], normalization: float }
|
|
1757
|
+
function diamond_count(mixedelements, wordshift) {
|
|
1758
|
+
|
|
1759
|
+
let deltas = wordshift["divergence_elements"];
|
|
1760
|
+
let sorted_div = matlab_sort(deltas, true);
|
|
1761
|
+
let indices_deltas = sorted_div.orig_idx;
|
|
1762
|
+
|
|
1763
|
+
deltas = indices_deltas.map(e => deltas[e]);
|
|
1764
|
+
|
|
1765
|
+
|
|
1766
|
+
mixedelements[0]['types'] = indices_deltas.map(i => mixedelements[0]['types'][i]);
|
|
1767
|
+
mixedelements[0]['counts'] = indices_deltas.map(i => mixedelements[0]['counts'][i]);
|
|
1768
|
+
mixedelements[0]['ranks'] = indices_deltas.map(i => mixedelements[0]['ranks'][i]);
|
|
1769
|
+
mixedelements[0]['probs'] = indices_deltas.map(i => mixedelements[0]['probs'][i]);
|
|
1770
|
+
|
|
1771
|
+
mixedelements[1]['types'] = indices_deltas.map(i => mixedelements[1]['types'][i]);
|
|
1772
|
+
mixedelements[1]['counts'] = indices_deltas.map(i => mixedelements[1]['counts'][i]);
|
|
1773
|
+
mixedelements[1]['ranks'] = indices_deltas.map(i => mixedelements[1]['ranks'][i]);
|
|
1774
|
+
mixedelements[1]['probs'] = indices_deltas.map(i => mixedelements[1]['probs'][i]);
|
|
1775
|
+
|
|
1776
|
+
const deltas_loss = structuredClone$1(deltas);
|
|
1777
|
+
const deltas_gain = structuredClone$1(deltas);
|
|
1778
|
+
|
|
1779
|
+
which(mixedelements[0]['ranks'].map((d,i) => mixedelements[0]['ranks'][i] > mixedelements[1]['ranks'][i])).map(e => deltas_loss[e] = -1);
|
|
1780
|
+
which(mixedelements[0]['ranks'].map((d,i) => mixedelements[1]['ranks'][i] < mixedelements[1]['ranks'][i])).map(e => deltas_gain[e] = -1);
|
|
1781
|
+
|
|
1782
|
+
|
|
1783
|
+
const counts = diamond_counts(mixedelements);
|
|
1784
|
+
|
|
1785
|
+
return({'counts': counts, 'deltas': deltas, 'max_delta_loss': Math.max(...deltas_loss)})
|
|
497
1786
|
}
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
Diamond,
|
|
501
|
-
DivergingBarChart,
|
|
502
|
-
Legend,
|
|
503
|
-
Test,
|
|
504
|
-
Wordshift
|
|
505
|
-
};
|
|
1787
|
+
|
|
1788
|
+
export { Dashboard, Diamond, DivergingBarChart, Legend, Wordshift, balanceDat, combElems, diamond_count, matlab_sort, rank_maxlog10, rank_turbulence_divergence, rin, tiedrank, which, wordShift_dat, zeros };
|