@platforma-sdk/model 1.21.0 → 1.21.10
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 +5 -0
- package/dist/components/PFrameForGraphs.d.ts.map +1 -0
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +598 -539
- 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 +1 -1
- package/src/components/PFrameForGraphs.test.ts +141 -0
- package/src/components/PFrameForGraphs.ts +112 -0
- package/src/components/index.ts +1 -0
package/dist/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const PlatformaSDKVersion = "1.21.
|
|
1
|
+
export declare const PlatformaSDKVersion = "1.21.10";
|
|
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
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import {test, expect, describe} from '@jest/globals';
|
|
2
|
+
import {getAdditionalColumns} from './PFrameForGraphs';
|
|
3
|
+
import {PColumn, PColumnSpec, PColumnValues, PObjectId} from "@milaboratories/pl-model-common";
|
|
4
|
+
import {TreeNodeAccessor} from "../render";
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
describe('PFrameForGraph', () => {
|
|
8
|
+
test('columns are compatible, no additional columns', () => {
|
|
9
|
+
const columnSpec1:PColumnSpec = {
|
|
10
|
+
kind: 'PColumn',
|
|
11
|
+
name: 'column1',
|
|
12
|
+
valueType: 'Int',
|
|
13
|
+
axesSpec: [
|
|
14
|
+
{type: 'String', name: 'axis1', domain: {}},
|
|
15
|
+
{type: 'Int', name: 'axis2', domain: {}}
|
|
16
|
+
]
|
|
17
|
+
}
|
|
18
|
+
const columnSpec2:PColumnSpec = {
|
|
19
|
+
kind: 'PColumn',
|
|
20
|
+
name: 'column2',
|
|
21
|
+
valueType: 'Int',
|
|
22
|
+
axesSpec: [{type: 'String', name: 'axis1', domain: {}}]
|
|
23
|
+
}
|
|
24
|
+
const columns:PColumn<TreeNodeAccessor | PColumnValues>[] = [{
|
|
25
|
+
id: 'id1' as PObjectId,
|
|
26
|
+
spec: columnSpec1,
|
|
27
|
+
data: []
|
|
28
|
+
}, {
|
|
29
|
+
id: 'id2' as PObjectId,
|
|
30
|
+
spec: columnSpec2,
|
|
31
|
+
data: []
|
|
32
|
+
}
|
|
33
|
+
] as PColumn<PColumnValues>[]
|
|
34
|
+
|
|
35
|
+
expect(getAdditionalColumns(columns).length).toEqual(0);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
test('columns are not compatible, 1 additional column', () => {
|
|
39
|
+
const columnSpec1:PColumnSpec = {
|
|
40
|
+
kind: 'PColumn',
|
|
41
|
+
name: 'column1',
|
|
42
|
+
valueType: 'Int',
|
|
43
|
+
axesSpec: [{type: 'String', name: 'axis1', domain: {key1: 'a'}}]
|
|
44
|
+
}
|
|
45
|
+
const columnSpec2:PColumnSpec = {
|
|
46
|
+
kind: 'PColumn',
|
|
47
|
+
name: 'column2',
|
|
48
|
+
valueType: 'Int',
|
|
49
|
+
axesSpec: [{type: 'String', name: 'axis1', domain: {}}]
|
|
50
|
+
}
|
|
51
|
+
const columns:PColumn<TreeNodeAccessor | PColumnValues>[] = [
|
|
52
|
+
{id: 'id1' as PObjectId, spec: columnSpec1, data: []},
|
|
53
|
+
{id: 'id2' as PObjectId, spec: columnSpec2, data: []}
|
|
54
|
+
] as PColumn<PColumnValues>[]
|
|
55
|
+
|
|
56
|
+
const additionalColumns = getAdditionalColumns(columns);
|
|
57
|
+
expect(additionalColumns.length).toEqual(1);
|
|
58
|
+
expect(additionalColumns[0].id === columns[0].id).toEqual(false);
|
|
59
|
+
expect(additionalColumns[0].id === columns[1].id).toEqual(false);
|
|
60
|
+
expect(additionalColumns[0].spec).toEqual({
|
|
61
|
+
kind: 'PColumn',
|
|
62
|
+
name: 'column2',
|
|
63
|
+
valueType: 'Int',
|
|
64
|
+
axesSpec: [{type: 'String', name: 'axis1', domain: {key1: 'a'}}]
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
test('columns are not compatible, additional columns are impossible', () => {
|
|
68
|
+
const columnSpec1:PColumnSpec = {
|
|
69
|
+
kind: 'PColumn',
|
|
70
|
+
name: 'column1',
|
|
71
|
+
valueType: 'Int',
|
|
72
|
+
axesSpec: [{type: 'String', name: 'axis1', domain: {key1: 'a'}}]
|
|
73
|
+
}
|
|
74
|
+
const columnSpec2:PColumnSpec = {
|
|
75
|
+
kind: 'PColumn',
|
|
76
|
+
name: 'column2',
|
|
77
|
+
valueType: 'Int',
|
|
78
|
+
axesSpec: [{type: 'String', name: 'axis1', domain: {key2: 'b'}}]
|
|
79
|
+
}
|
|
80
|
+
const columns:PColumn<TreeNodeAccessor | PColumnValues>[] = [
|
|
81
|
+
{id: 'id1' as PObjectId, spec: columnSpec1, data: []},
|
|
82
|
+
{id: 'id2' as PObjectId, spec: columnSpec2, data: []}
|
|
83
|
+
] as PColumn<PColumnValues>[]
|
|
84
|
+
|
|
85
|
+
const additionalColumns = getAdditionalColumns(columns);
|
|
86
|
+
expect(additionalColumns.length).toEqual(0);
|
|
87
|
+
});
|
|
88
|
+
test('columns are not compatible, 2 additional columns', () => {
|
|
89
|
+
const columnSpec1:PColumnSpec = {
|
|
90
|
+
kind: 'PColumn',
|
|
91
|
+
name: 'column1',
|
|
92
|
+
valueType: 'Int',
|
|
93
|
+
axesSpec: [
|
|
94
|
+
{type: 'String', name: 'axis1', domain: {key1: 'a'}},
|
|
95
|
+
{type: 'String', name: 'axis1', domain: {key1: 'b'}},
|
|
96
|
+
]
|
|
97
|
+
}
|
|
98
|
+
const columnSpec2:PColumnSpec = {
|
|
99
|
+
kind: 'PColumn',
|
|
100
|
+
name: 'column2',
|
|
101
|
+
valueType: 'Int',
|
|
102
|
+
axesSpec: [{type: 'String', name: 'axis1', domain: {}}]
|
|
103
|
+
}
|
|
104
|
+
const columns:PColumn<TreeNodeAccessor | PColumnValues>[] = [
|
|
105
|
+
{id: 'id1' as PObjectId, spec: columnSpec1, data: []},
|
|
106
|
+
{id: 'id2' as PObjectId, spec: columnSpec2, data: []}
|
|
107
|
+
] as PColumn<PColumnValues>[]
|
|
108
|
+
|
|
109
|
+
const additionalColumns = getAdditionalColumns(columns);
|
|
110
|
+
expect(additionalColumns.length).toEqual(2);
|
|
111
|
+
});
|
|
112
|
+
test('columns are not compatible, 4 additional columns - by 2 axes', () => {
|
|
113
|
+
const columnSpec1:PColumnSpec = {
|
|
114
|
+
kind: 'PColumn',
|
|
115
|
+
name: 'column1',
|
|
116
|
+
valueType: 'Int',
|
|
117
|
+
axesSpec: [
|
|
118
|
+
{type: 'String', name: 'axis1', domain: {key1: 'a'}},
|
|
119
|
+
{type: 'String', name: 'axis1', domain: {key1: 'b'}},
|
|
120
|
+
{type: 'String', name: 'axis2', domain: {key1: 'a'}},
|
|
121
|
+
{type: 'String', name: 'axis2', domain: {key1: 'b'}},
|
|
122
|
+
]
|
|
123
|
+
}
|
|
124
|
+
const columnSpec2:PColumnSpec = {
|
|
125
|
+
kind: 'PColumn',
|
|
126
|
+
name: 'column2',
|
|
127
|
+
valueType: 'Int',
|
|
128
|
+
axesSpec: [
|
|
129
|
+
{type: 'String', name: 'axis1', domain: {}},
|
|
130
|
+
{type: 'String', name: 'axis2', domain: {}}
|
|
131
|
+
]
|
|
132
|
+
}
|
|
133
|
+
const columns:PColumn<TreeNodeAccessor | PColumnValues>[] = [
|
|
134
|
+
{id: 'id1' as PObjectId, spec: columnSpec1, data: []},
|
|
135
|
+
{id: 'id2' as PObjectId, spec: columnSpec2, data: []}
|
|
136
|
+
] as PColumn<PColumnValues>[]
|
|
137
|
+
|
|
138
|
+
const additionalColumns = getAdditionalColumns(columns);
|
|
139
|
+
expect(additionalColumns.length).toEqual(4);
|
|
140
|
+
});
|
|
141
|
+
})
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AxisId,
|
|
3
|
+
getAxisId,
|
|
4
|
+
matchAxisId,
|
|
5
|
+
PColumn,
|
|
6
|
+
PColumnValues, PFrameHandle,
|
|
7
|
+
PObjectId,
|
|
8
|
+
} from '@milaboratories/pl-model-common';
|
|
9
|
+
import { RenderCtx, TreeNodeAccessor } from '../render';
|
|
10
|
+
|
|
11
|
+
/** Create id for column copy with added keys in axes domains */
|
|
12
|
+
const colId = (id: PObjectId, domains: (Record<string, string> | undefined)[]) => {
|
|
13
|
+
let wid = id.toString();
|
|
14
|
+
domains?.forEach(domain => {
|
|
15
|
+
if (domain) {
|
|
16
|
+
for (const [k, v] of Object.entries(domain)) {
|
|
17
|
+
wid += k;
|
|
18
|
+
wid += v;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
return wid;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
/** All combinations with 1 key from each list */
|
|
26
|
+
function getKeysCombinations(idsLists: AxisId[][]) {
|
|
27
|
+
if (!idsLists.length) {
|
|
28
|
+
return [];
|
|
29
|
+
}
|
|
30
|
+
let result: AxisId[][] = [[]];
|
|
31
|
+
idsLists.forEach(list => {
|
|
32
|
+
const nextResult: AxisId[][] = [];
|
|
33
|
+
list.forEach(key => {
|
|
34
|
+
nextResult.push(...result.map(resultItem => [...resultItem, key]));
|
|
35
|
+
});
|
|
36
|
+
result = nextResult;
|
|
37
|
+
});
|
|
38
|
+
return result;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Main column can have additional domains, if secondary column (meta-column) has all axes match main column axes
|
|
42
|
+
we can add its copy with missed domain fields for compatibility */
|
|
43
|
+
function getAdditionalColumnsForPair(
|
|
44
|
+
mainColumn: PColumn<TreeNodeAccessor | PColumnValues>,
|
|
45
|
+
secondaryColumn: PColumn<TreeNodeAccessor | PColumnValues>
|
|
46
|
+
): PColumn<TreeNodeAccessor | PColumnValues>[] {
|
|
47
|
+
const mainAxesIds = mainColumn.spec.axesSpec.map(getAxisId);
|
|
48
|
+
const secondaryAxesIds = secondaryColumn.spec.axesSpec.map(getAxisId);
|
|
49
|
+
|
|
50
|
+
const isFullCompatible = secondaryAxesIds.every(id => mainAxesIds.some(mainId => matchAxisId(mainId, id) && matchAxisId(id, mainId)));
|
|
51
|
+
if (isFullCompatible) { // in this case it isn't necessary to add more columns
|
|
52
|
+
return [];
|
|
53
|
+
}
|
|
54
|
+
const isCompatible = secondaryAxesIds.every(id => mainAxesIds.some(mainId => matchAxisId(mainId, id)));
|
|
55
|
+
if (!isCompatible) { // in this case it is impossible to add some compatible column
|
|
56
|
+
return [];
|
|
57
|
+
}
|
|
58
|
+
// options with different possible domains for every axis of secondary column
|
|
59
|
+
const secondaryIdsOptions = secondaryAxesIds.map(id => {
|
|
60
|
+
return mainAxesIds.filter(mainId => matchAxisId(mainId, id));
|
|
61
|
+
});
|
|
62
|
+
// all possible combinations of axes with added domains
|
|
63
|
+
const secondaryIdsVariants = getKeysCombinations(secondaryIdsOptions);
|
|
64
|
+
|
|
65
|
+
return secondaryIdsVariants.map(idsList => {
|
|
66
|
+
const id = colId(secondaryColumn.id, idsList.map(id => id.domain));
|
|
67
|
+
return {
|
|
68
|
+
id: id as PObjectId,
|
|
69
|
+
spec: {
|
|
70
|
+
...secondaryColumn.spec,
|
|
71
|
+
axesSpec: idsList.map((axisId, idx) => ({
|
|
72
|
+
...axisId,
|
|
73
|
+
annotations: secondaryColumn.spec.axesSpec[idx].annotations
|
|
74
|
+
}))
|
|
75
|
+
},
|
|
76
|
+
data: secondaryColumn.data
|
|
77
|
+
};
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export function getAdditionalColumns(columns: PColumn<TreeNodeAccessor | PColumnValues>[]):PColumn<TreeNodeAccessor | PColumnValues>[] {
|
|
82
|
+
const additionalColumns: PColumn<TreeNodeAccessor | PColumnValues>[] = [];
|
|
83
|
+
for (let i = 0; i < columns.length; i++) {
|
|
84
|
+
for (let j = i + 1; j < columns.length; j++) {
|
|
85
|
+
const column1 = columns[i];
|
|
86
|
+
const column2 = columns[j];
|
|
87
|
+
|
|
88
|
+
// check if column 1 is meta for column 2 or backward
|
|
89
|
+
additionalColumns.push(
|
|
90
|
+
...getAdditionalColumnsForPair(column1, column2),
|
|
91
|
+
...getAdditionalColumnsForPair(column2, column1)
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return additionalColumns;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export function createPFrameForGraphs<A, U>(
|
|
99
|
+
ctx: RenderCtx<A, U>,
|
|
100
|
+
columns: PColumn<TreeNodeAccessor | PColumnValues>[]
|
|
101
|
+
): PFrameHandle | undefined {
|
|
102
|
+
const extendedColumns = [...columns, ...getAdditionalColumns(columns)];
|
|
103
|
+
// if at least one column is not yet ready, we can't show the table
|
|
104
|
+
if (
|
|
105
|
+
extendedColumns.some(
|
|
106
|
+
(a) => a.data instanceof TreeNodeAccessor && !a.data.getIsReadyOrError()
|
|
107
|
+
)
|
|
108
|
+
)
|
|
109
|
+
return undefined;
|
|
110
|
+
|
|
111
|
+
return ctx.createPFrame(extendedColumns);
|
|
112
|
+
}
|
package/src/components/index.ts
CHANGED