@platforma-sdk/model 1.30.3 → 1.30.21
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/components/PFrameForGraphs.d.ts +4 -4
- package/dist/components/PFrameForGraphs.d.ts.map +1 -1
- package/dist/components/PlDataTable.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +342 -345
- package/dist/index.mjs.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/components/PFrameForGraphs.ts +27 -33
- package/src/components/PlDataTable.ts +58 -29
- package/src/render/util/label.ts +13 -13
package/dist/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const PlatformaSDKVersion = "1.30.
|
|
1
|
+
export declare const PlatformaSDKVersion = "1.30.21";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/version.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,mBAAmB,
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,mBAAmB,YAAY,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platforma-sdk/model",
|
|
3
|
-
"version": "1.30.
|
|
3
|
+
"version": "1.30.21",
|
|
4
4
|
"description": "Platforma.bio SDK / Block Model",
|
|
5
5
|
"types": "./dist/index.d.ts",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"utility-types": "^3.11.0",
|
|
22
22
|
"canonicalize": "~2.1.0",
|
|
23
23
|
"zod": "~3.23.8",
|
|
24
|
-
"@milaboratories/pl-model-common": "^1.14.
|
|
24
|
+
"@milaboratories/pl-model-common": "^1.14.1",
|
|
25
25
|
"@milaboratories/pl-error-like": "^1.12.1"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
@@ -31,8 +31,8 @@
|
|
|
31
31
|
"jest": "^29.7.0",
|
|
32
32
|
"@jest/globals": "^29.7.0",
|
|
33
33
|
"ts-jest": "^29.2.6",
|
|
34
|
-
"@platforma-
|
|
35
|
-
"@
|
|
34
|
+
"@milaboratories/platforma-build-configs": "1.0.3",
|
|
35
|
+
"@platforma-sdk/eslint-config": "1.0.3"
|
|
36
36
|
},
|
|
37
37
|
"scripts": {
|
|
38
38
|
"type-check": "node ./scripts/save-package-version.cjs && tsc --noEmit --composite false",
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
AxisId,
|
|
3
3
|
CanonicalizedJson,
|
|
4
|
+
DataInfo,
|
|
4
5
|
PColumn,
|
|
6
|
+
PColumnSpec,
|
|
5
7
|
PColumnSpecId,
|
|
6
8
|
PColumnValues,
|
|
7
9
|
PFrameHandle,
|
|
8
10
|
PObjectId,
|
|
9
|
-
|
|
11
|
+
} from '@milaboratories/pl-model-common';
|
|
10
12
|
import {
|
|
11
13
|
canonicalizeJson,
|
|
12
14
|
getAxisId,
|
|
@@ -49,21 +51,21 @@ function getKeysCombinations(idsLists: AxisId[][]) {
|
|
|
49
51
|
|
|
50
52
|
/** Check if axes of secondary column are exactly in axes of main column */
|
|
51
53
|
function checkFullCompatibility(
|
|
52
|
-
mainColumn:
|
|
53
|
-
secondaryColumn:
|
|
54
|
+
mainColumn: PColumnSpec,
|
|
55
|
+
secondaryColumn: PColumnSpec,
|
|
54
56
|
): boolean {
|
|
55
|
-
const mainAxesIds = mainColumn.
|
|
56
|
-
const secondaryAxesIds = secondaryColumn.
|
|
57
|
+
const mainAxesIds = mainColumn.axesSpec.map(getAxisId);
|
|
58
|
+
const secondaryAxesIds = secondaryColumn.axesSpec.map(getAxisId);
|
|
57
59
|
return secondaryAxesIds.every((id) => mainAxesIds.some((mainId) => matchAxisId(mainId, id) && matchAxisId(id, mainId)));
|
|
58
60
|
}
|
|
59
61
|
|
|
60
62
|
/** Check if axes of secondary column are in axes of main column, but they can have compatible difference in domains */
|
|
61
63
|
function checkCompatibility(
|
|
62
|
-
mainColumn:
|
|
63
|
-
secondaryColumn:
|
|
64
|
+
mainColumn: PColumnSpec,
|
|
65
|
+
secondaryColumn: PColumnSpec,
|
|
64
66
|
): boolean {
|
|
65
|
-
const mainAxesIds = mainColumn.
|
|
66
|
-
const secondaryAxesIds = secondaryColumn.
|
|
67
|
+
const mainAxesIds = mainColumn.axesSpec.map(getAxisId);
|
|
68
|
+
const secondaryAxesIds = secondaryColumn.axesSpec.map(getAxisId);
|
|
67
69
|
return secondaryAxesIds.every((id) => mainAxesIds.some((mainId) => matchAxisId(mainId, id)));
|
|
68
70
|
}
|
|
69
71
|
|
|
@@ -73,17 +75,17 @@ export const LABEL_ANNOTATION = 'pl7.app/label';
|
|
|
73
75
|
/** Main column can have additional domains, if secondary column (meta-column) has all axes match main column axes
|
|
74
76
|
we can add its copy with missed domain fields for compatibility */
|
|
75
77
|
function getAdditionalColumnsForPair(
|
|
76
|
-
mainColumn: PColumn<TreeNodeAccessor | PColumnValues>,
|
|
77
|
-
secondaryColumn: PColumn<TreeNodeAccessor | PColumnValues>,
|
|
78
|
-
): PColumn<TreeNodeAccessor | PColumnValues>[] {
|
|
78
|
+
mainColumn: PColumn<TreeNodeAccessor | DataInfo<TreeNodeAccessor> | PColumnValues>,
|
|
79
|
+
secondaryColumn: PColumn<TreeNodeAccessor | DataInfo<TreeNodeAccessor> | PColumnValues>,
|
|
80
|
+
): PColumn<TreeNodeAccessor | DataInfo<TreeNodeAccessor> | PColumnValues>[] {
|
|
79
81
|
const mainAxesIds = mainColumn.spec.axesSpec.map(getAxisId);
|
|
80
82
|
const secondaryAxesIds = secondaryColumn.spec.axesSpec.map(getAxisId);
|
|
81
83
|
|
|
82
|
-
const isFullCompatible = checkFullCompatibility(mainColumn, secondaryColumn);
|
|
84
|
+
const isFullCompatible = checkFullCompatibility(mainColumn.spec, secondaryColumn.spec);
|
|
83
85
|
if (isFullCompatible) { // in this case it isn't necessary to add more columns
|
|
84
86
|
return [];
|
|
85
87
|
}
|
|
86
|
-
const isCompatible = checkCompatibility(mainColumn, secondaryColumn);
|
|
88
|
+
const isCompatible = checkCompatibility(mainColumn.spec, secondaryColumn.spec);
|
|
87
89
|
if (!isCompatible) { // in this case it is impossible to add some compatible column
|
|
88
90
|
return [];
|
|
89
91
|
}
|
|
@@ -155,8 +157,10 @@ function getAdditionalColumnsForPair(
|
|
|
155
157
|
});
|
|
156
158
|
}
|
|
157
159
|
|
|
158
|
-
export function getAdditionalColumns(
|
|
159
|
-
|
|
160
|
+
export function getAdditionalColumns(
|
|
161
|
+
columns: PColumn<TreeNodeAccessor | DataInfo<TreeNodeAccessor> | PColumnValues>[],
|
|
162
|
+
): PColumn<TreeNodeAccessor | DataInfo<TreeNodeAccessor> | PColumnValues>[] {
|
|
163
|
+
const additionalColumns: PColumn<TreeNodeAccessor | DataInfo<TreeNodeAccessor> | PColumnValues>[] = [];
|
|
160
164
|
for (let i = 0; i < columns.length; i++) {
|
|
161
165
|
for (let j = i + 1; j < columns.length; j++) {
|
|
162
166
|
const column1 = columns[i];
|
|
@@ -173,9 +177,9 @@ export function getAdditionalColumns(columns: PColumn<TreeNodeAccessor | PColumn
|
|
|
173
177
|
}
|
|
174
178
|
|
|
175
179
|
export function enrichColumnsWithCompatible(
|
|
176
|
-
mainColumns: PColumn<TreeNodeAccessor | PColumnValues>[],
|
|
177
|
-
secondaryColumns: PColumn<TreeNodeAccessor | PColumnValues>[],
|
|
178
|
-
): PColumn<TreeNodeAccessor | PColumnValues>[] {
|
|
180
|
+
mainColumns: PColumn<TreeNodeAccessor | DataInfo<TreeNodeAccessor> | PColumnValues>[],
|
|
181
|
+
secondaryColumns: PColumn<TreeNodeAccessor | DataInfo<TreeNodeAccessor> | PColumnValues>[],
|
|
182
|
+
): PColumn<TreeNodeAccessor | DataInfo<TreeNodeAccessor> | PColumnValues>[] {
|
|
179
183
|
const mainColumnsIds = new Set<PObjectId>();
|
|
180
184
|
const mainColumnsBySpec = new Map<CanonicalizedJson<PColumnSpecId>, typeof mainColumns[number]>();
|
|
181
185
|
mainColumns.forEach((column) => {
|
|
@@ -191,7 +195,7 @@ export function enrichColumnsWithCompatible(
|
|
|
191
195
|
if (mainColumnsBySpec.has(spec)) continue;
|
|
192
196
|
|
|
193
197
|
for (const mainColumn of mainColumnsBySpec.values()) {
|
|
194
|
-
if (checkCompatibility(mainColumn, secondaryColumn)) {
|
|
198
|
+
if (checkCompatibility(mainColumn.spec, secondaryColumn.spec)) {
|
|
195
199
|
secondaryColumnsBySpec.set(spec, secondaryColumn);
|
|
196
200
|
break;
|
|
197
201
|
}
|
|
@@ -201,26 +205,16 @@ export function enrichColumnsWithCompatible(
|
|
|
201
205
|
return [...mainColumnsBySpec.values(), ...secondaryColumnsBySpec.values()];
|
|
202
206
|
}
|
|
203
207
|
|
|
204
|
-
const VALUE_TYPES: ValueType[] = [
|
|
205
|
-
'Int',
|
|
206
|
-
'Long',
|
|
207
|
-
'Float',
|
|
208
|
-
'Double',
|
|
209
|
-
'String',
|
|
210
|
-
'Bytes',
|
|
211
|
-
];
|
|
212
|
-
|
|
213
208
|
export function createPFrameForGraphs<A, U>(
|
|
214
209
|
ctx: RenderCtx<A, U>,
|
|
215
|
-
blockColumns
|
|
210
|
+
blockColumns: PColumn<TreeNodeAccessor | DataInfo<TreeNodeAccessor> | PColumnValues>[] | undefined,
|
|
216
211
|
): PFrameHandle | undefined {
|
|
217
|
-
if (blockColumns
|
|
212
|
+
if (!blockColumns) return undefined;
|
|
218
213
|
|
|
219
214
|
const upstreamColumns = ctx.resultPool
|
|
220
215
|
.getData()
|
|
221
216
|
.entries.map((v) => v.obj)
|
|
222
|
-
.filter(isPColumn)
|
|
223
|
-
.filter((column) => VALUE_TYPES.includes(column.spec.valueType));
|
|
217
|
+
.filter(isPColumn);
|
|
224
218
|
|
|
225
219
|
const columnsWithCompatibleFromUpstream = enrichColumnsWithCompatible(blockColumns, upstreamColumns);
|
|
226
220
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type {
|
|
2
|
+
AxisId,
|
|
2
3
|
AxisSpec,
|
|
3
4
|
CanonicalizedJson,
|
|
4
5
|
DataInfo,
|
|
@@ -365,7 +366,39 @@ export function getMatchingLabelColumns(
|
|
|
365
366
|
columns: PColumnIdAndSpec[],
|
|
366
367
|
allLabelColumns: PColumn<TreeNodeAccessor | DataInfo<TreeNodeAccessor>>[],
|
|
367
368
|
): PColumn<TreeNodeAccessor | DataInfo<TreeNodeAccessor>>[] {
|
|
368
|
-
|
|
369
|
+
// split input columns into label and value columns
|
|
370
|
+
const inputLabelColumns: typeof columns = [];
|
|
371
|
+
const inputValueColumns: typeof columns = [];
|
|
372
|
+
for (const column of columns) {
|
|
373
|
+
if (isLabelColumn(column.spec)) {
|
|
374
|
+
inputLabelColumns.push(column);
|
|
375
|
+
} else {
|
|
376
|
+
inputValueColumns.push(column);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
// collect distinct axes of value columns
|
|
381
|
+
const unlabeledAxes: AxisId[] = [];
|
|
382
|
+
for (const column of inputValueColumns) {
|
|
383
|
+
for (const axis of column.spec.axesSpec) {
|
|
384
|
+
const axisId = getAxisId(axis);
|
|
385
|
+
if (!unlabeledAxes.some((id) => matchAxisId(id, axisId))) {
|
|
386
|
+
unlabeledAxes.push(axisId);
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
// remove axes matched by input label columns
|
|
392
|
+
for (const labelColumn of inputLabelColumns) {
|
|
393
|
+
const labelAxisId = getAxisId(labelColumn.spec.axesSpec[0]);
|
|
394
|
+
const labelMatch = unlabeledAxes.findIndex((axisId) => matchAxisId(axisId, labelAxisId));
|
|
395
|
+
if (labelMatch !== -1) {
|
|
396
|
+
unlabeledAxes.splice(labelMatch, 1);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
// warning: changing this id will break backward compatibility
|
|
401
|
+
const colId = (id: PObjectId, domain?: Record<string, string>): PObjectId => {
|
|
369
402
|
let wid = id.toString();
|
|
370
403
|
if (domain) {
|
|
371
404
|
for (const k in domain) {
|
|
@@ -373,39 +406,35 @@ export function getMatchingLabelColumns(
|
|
|
373
406
|
wid += domain[k];
|
|
374
407
|
}
|
|
375
408
|
}
|
|
376
|
-
return wid;
|
|
409
|
+
return wid as PObjectId;
|
|
377
410
|
};
|
|
378
411
|
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
} else {
|
|
401
|
-
labelColumns.set(colId(labelColumn.id), labelColumn);
|
|
402
|
-
}
|
|
403
|
-
}
|
|
412
|
+
// search label columns for unmatched axes
|
|
413
|
+
const labelColumns: typeof allLabelColumns = [];
|
|
414
|
+
for (const labelColumn of allLabelColumns) {
|
|
415
|
+
const labelAxis = labelColumn.spec.axesSpec[0];
|
|
416
|
+
const labelAxisId = getAxisId(labelAxis);
|
|
417
|
+
const labelMatch = unlabeledAxes.findIndex((axisId) => matchAxisId(axisId, labelAxisId));
|
|
418
|
+
if (labelMatch !== -1) {
|
|
419
|
+
const axisId = unlabeledAxes[labelMatch];
|
|
420
|
+
const dataDomainLen = Object.keys(axisId.domain ?? {}).length;
|
|
421
|
+
const labelDomainLen = Object.keys(labelAxis.domain ?? {}).length;
|
|
422
|
+
if (dataDomainLen > labelDomainLen) {
|
|
423
|
+
labelColumns.push({
|
|
424
|
+
id: colId(labelColumn.id, axisId.domain),
|
|
425
|
+
spec: {
|
|
426
|
+
...labelColumn.spec,
|
|
427
|
+
axesSpec: [{ ...axisId, annotations: labelAxis.annotations }],
|
|
428
|
+
},
|
|
429
|
+
data: labelColumn.data,
|
|
430
|
+
});
|
|
431
|
+
} else {
|
|
432
|
+
labelColumns.push(labelColumn);
|
|
404
433
|
}
|
|
434
|
+
unlabeledAxes.splice(labelMatch, 1);
|
|
405
435
|
}
|
|
406
436
|
}
|
|
407
|
-
|
|
408
|
-
return [...labelColumns.values()];
|
|
437
|
+
return labelColumns;
|
|
409
438
|
}
|
|
410
439
|
|
|
411
440
|
/** Check if all columns are computed */
|
package/src/render/util/label.ts
CHANGED
|
@@ -25,7 +25,7 @@ export const TraceEntry = z.object({
|
|
|
25
25
|
label: z.string(),
|
|
26
26
|
});
|
|
27
27
|
export type TraceEntry = z.infer<typeof TraceEntry>;
|
|
28
|
-
type FullTraceEntry = TraceEntry & { fullType: string;
|
|
28
|
+
type FullTraceEntry = TraceEntry & { fullType: string; occurrenceIndex: number };
|
|
29
29
|
|
|
30
30
|
export const Trace = z.array(TraceEntry);
|
|
31
31
|
export type Trace = z.infer<typeof Trace>;
|
|
@@ -50,7 +50,7 @@ export function deriveLabels<T>(
|
|
|
50
50
|
): RecordsWithLabel<T>[] {
|
|
51
51
|
const importances = new Map<string, number>();
|
|
52
52
|
|
|
53
|
-
// number of times certain type
|
|
53
|
+
// number of times certain type occurred among all of the
|
|
54
54
|
const numberOfRecordsWithType = new Map<string, number>();
|
|
55
55
|
|
|
56
56
|
const enrichedRecords = values.map((value) => {
|
|
@@ -88,13 +88,13 @@ export function deriveLabels<T>(
|
|
|
88
88
|
|
|
89
89
|
const fullTrace: FullTrace = [];
|
|
90
90
|
|
|
91
|
-
const
|
|
91
|
+
const occurrences = new Map<string, number>();
|
|
92
92
|
for (let i = trace.length - 1; i >= 0; --i) {
|
|
93
93
|
const { type: typeName } = trace[i];
|
|
94
94
|
const importance = trace[i].importance ?? 0;
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
const fullType = `${typeName}@${
|
|
95
|
+
const occurrenceIndex = (occurrences.get(typeName) ?? 0) + 1;
|
|
96
|
+
occurrences.set(typeName, occurrenceIndex);
|
|
97
|
+
const fullType = `${typeName}@${occurrenceIndex}`;
|
|
98
98
|
numberOfRecordsWithType.set(fullType, (numberOfRecordsWithType.get(fullType) ?? 0) + 1);
|
|
99
99
|
importances.set(
|
|
100
100
|
fullType,
|
|
@@ -103,7 +103,7 @@ export function deriveLabels<T>(
|
|
|
103
103
|
importance - (trace.length - i) * DistancePenalty,
|
|
104
104
|
),
|
|
105
105
|
);
|
|
106
|
-
fullTrace.push({ ...trace[i], fullType,
|
|
106
|
+
fullTrace.push({ ...trace[i], fullType, occurrenceIndex: occurrenceIndex });
|
|
107
107
|
}
|
|
108
108
|
fullTrace.reverse();
|
|
109
109
|
return {
|
|
@@ -160,27 +160,27 @@ export function deriveLabels<T>(
|
|
|
160
160
|
// * *
|
|
161
161
|
// T0 T1 T2 T3 T4 T5
|
|
162
162
|
// *
|
|
163
|
-
//
|
|
163
|
+
// additionalType = 3
|
|
164
164
|
//
|
|
165
165
|
// Resulting set: T0, T1, T3
|
|
166
166
|
//
|
|
167
167
|
let includedTypes = 0;
|
|
168
|
-
let
|
|
168
|
+
let additionalType = 0;
|
|
169
169
|
while (includedTypes < mainTypes.length) {
|
|
170
170
|
const currentSet = new Set<string>();
|
|
171
171
|
if (ops.includeNativeLabel) currentSet.add(LabelTypeFull);
|
|
172
172
|
for (let i = 0; i < includedTypes; ++i) currentSet.add(mainTypes[i]);
|
|
173
|
-
currentSet.add(mainTypes[
|
|
173
|
+
currentSet.add(mainTypes[additionalType]);
|
|
174
174
|
|
|
175
175
|
const candidateResult = calculate(currentSet);
|
|
176
176
|
|
|
177
177
|
// checking if labels uniquely separate our records
|
|
178
178
|
if (candidateResult !== undefined && new Set(candidateResult.map((c) => c.label)).size === values.length) return candidateResult;
|
|
179
179
|
|
|
180
|
-
|
|
181
|
-
if (
|
|
180
|
+
additionalType++;
|
|
181
|
+
if (additionalType >= mainTypes.length) {
|
|
182
182
|
includedTypes++;
|
|
183
|
-
|
|
183
|
+
additionalType = includedTypes;
|
|
184
184
|
}
|
|
185
185
|
}
|
|
186
186
|
|