@kanaries/graphic-walker 0.3.4 → 0.3.5
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/assets/viewQuery.worker-03404216.js.map +1 -0
- package/dist/components/pivotTable/index.d.ts +12 -0
- package/dist/components/pivotTable/inteface.d.ts +6 -0
- package/dist/components/pivotTable/leftTree.d.ts +10 -0
- package/dist/components/pivotTable/metricTable.d.ts +9 -0
- package/dist/components/pivotTable/store.d.ts +22 -0
- package/dist/components/pivotTable/topTree.d.ts +10 -0
- package/dist/components/pivotTable/utils.d.ts +6 -0
- package/dist/components/visualConfig/index.d.ts +3 -0
- package/dist/config.d.ts +2 -0
- package/dist/fields/aestheticFields.d.ts +2 -2
- package/dist/graphic-walker.es.js +23167 -22784
- package/dist/graphic-walker.es.js.map +1 -1
- package/dist/graphic-walker.umd.js +127 -127
- package/dist/graphic-walker.umd.js.map +1 -1
- package/dist/interfaces.d.ts +6 -0
- package/dist/lib/insights/utils.d.ts +0 -2
- package/dist/lib/interfaces.d.ts +5 -3
- package/dist/store/commonStore.d.ts +2 -0
- package/dist/store/visualSpecStore.d.ts +1 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/vis/react-vega.d.ts +3 -1
- package/dist/vis/spec/encode.d.ts +2 -0
- package/package.json +1 -1
- package/src/App.tsx +2 -0
- package/src/components/pivotTable/index.tsx +119 -0
- package/src/components/pivotTable/inteface.ts +8 -0
- package/src/components/pivotTable/leftTree.tsx +92 -0
- package/src/components/pivotTable/metricTable.tsx +107 -0
- package/src/components/pivotTable/store.tsx +66 -0
- package/src/components/pivotTable/topTree.tsx +77 -0
- package/src/components/pivotTable/utils.ts +141 -0
- package/src/components/visualConfig/index.tsx +76 -0
- package/src/config.ts +5 -1
- package/src/fields/aestheticFields.tsx +25 -4
- package/src/fields/components.tsx +2 -2
- package/src/fields/fieldsContext.tsx +2 -1
- package/src/interfaces.ts +6 -0
- package/src/lib/insights/explainByChildren.ts +11 -3
- package/src/lib/insights/explainBySelection.ts +14 -5
- package/src/lib/insights/explainValue.ts +10 -3
- package/src/lib/insights/utils.ts +0 -4
- package/src/lib/interfaces.ts +1 -3
- package/src/lib/op/aggregate.ts +9 -7
- package/src/locales/en-US.json +11 -2
- package/src/locales/ja-JP.json +187 -178
- package/src/locales/zh-CN.json +11 -2
- package/src/renderer/index.tsx +16 -2
- package/src/renderer/specRenderer.tsx +6 -2
- package/src/store/commonStore.ts +4 -0
- package/src/store/visualSpecStore.ts +12 -0
- package/src/utils/index.ts +7 -0
- package/src/vis/react-vega.tsx +31 -7
- package/src/vis/spec/aggregate.ts +3 -0
- package/src/vis/spec/encode.ts +5 -1
- package/src/vis/spec/view.ts +4 -2
- package/src/visualSettings/index.tsx +11 -0
- package/dist/assets/viewQuery.worker-ffefc111.js.map +0 -1
package/src/vis/react-vega.tsx
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import React, { useEffect, useState, useMemo, forwardRef, useImperativeHandle, useRef } from 'react';
|
|
2
|
-
import embed from 'vega-embed';
|
|
2
|
+
import embed, { vega } from 'vega-embed';
|
|
3
3
|
import { Subject, Subscription } from 'rxjs'
|
|
4
4
|
import * as op from 'rxjs/operators';
|
|
5
5
|
import type { ScenegraphEvent, View } from 'vega';
|
|
6
6
|
import styled from 'styled-components';
|
|
7
7
|
|
|
8
|
-
import { IViewField, IRow, IStackMode, IDarkMode, IThemeKey } from '../interfaces';
|
|
8
|
+
import { IViewField, IRow, IStackMode, IDarkMode, IThemeKey, IVisualConfig } from '../interfaces';
|
|
9
9
|
import { useTranslation } from 'react-i18next';
|
|
10
10
|
import { getVegaTimeFormatRules } from './temporalFormat';
|
|
11
11
|
import { builtInThemes } from './theme';
|
|
@@ -27,6 +27,7 @@ export interface IReactVegaHandler {
|
|
|
27
27
|
downloadPNG: (filename?: string) => Promise<string[]>;
|
|
28
28
|
}
|
|
29
29
|
interface ReactVegaProps {
|
|
30
|
+
format: IVisualConfig['format'];
|
|
30
31
|
rows: Readonly<IViewField[]>;
|
|
31
32
|
columns: Readonly<IViewField[]>;
|
|
32
33
|
dataSource: IRow[];
|
|
@@ -40,6 +41,7 @@ interface ReactVegaProps {
|
|
|
40
41
|
shape?: IViewField;
|
|
41
42
|
theta?: IViewField;
|
|
42
43
|
radius?: IViewField;
|
|
44
|
+
text?: IViewField;
|
|
43
45
|
details?: Readonly<IViewField[]>;
|
|
44
46
|
showActions: boolean;
|
|
45
47
|
layoutMode: string;
|
|
@@ -88,6 +90,7 @@ const ReactVega = forwardRef<IReactVegaHandler, ReactVegaProps>(function ReactVe
|
|
|
88
90
|
theta,
|
|
89
91
|
radius,
|
|
90
92
|
shape,
|
|
93
|
+
text,
|
|
91
94
|
onGeomClick,
|
|
92
95
|
showActions,
|
|
93
96
|
interactiveScale,
|
|
@@ -96,12 +99,30 @@ const ReactVega = forwardRef<IReactVegaHandler, ReactVegaProps>(function ReactVe
|
|
|
96
99
|
height,
|
|
97
100
|
details = [],
|
|
98
101
|
themeKey = 'vega',
|
|
99
|
-
dark = 'media'
|
|
102
|
+
dark = 'media',
|
|
103
|
+
format
|
|
100
104
|
} = props;
|
|
101
105
|
const [viewPlaceholders, setViewPlaceholders] = useState<React.MutableRefObject<HTMLDivElement>[]>([]);
|
|
102
106
|
const { i18n } = useTranslation();
|
|
103
107
|
const mediaTheme = useCurrentMediaTheme(dark);
|
|
104
108
|
const themeConfig = builtInThemes[themeKey]?.[mediaTheme];
|
|
109
|
+
|
|
110
|
+
const vegaConfig = useMemo(() => {
|
|
111
|
+
const config: any = {
|
|
112
|
+
...themeConfig,
|
|
113
|
+
}
|
|
114
|
+
if (format.normalizedNumberFormat && format.normalizedNumberFormat.length > 0) {
|
|
115
|
+
config.normalizedNumberFormat = format.normalizedNumberFormat;
|
|
116
|
+
}
|
|
117
|
+
if (format.numberFormat && format.numberFormat.length > 0) {
|
|
118
|
+
config.numberFormat = format.numberFormat;
|
|
119
|
+
}
|
|
120
|
+
if (format.timeFormat && format.timeFormat.length > 0) {
|
|
121
|
+
config.timeFormat = format.timeFormat;
|
|
122
|
+
}
|
|
123
|
+
return config;
|
|
124
|
+
}, [themeConfig, format.normalizedNumberFormat, format.numberFormat, format.timeFormat])
|
|
125
|
+
|
|
105
126
|
useEffect(() => {
|
|
106
127
|
const clickSub = geomClick$.subscribe(([values, e]) => {
|
|
107
128
|
if (onGeomClick) {
|
|
@@ -183,6 +204,7 @@ const ReactVega = forwardRef<IReactVegaHandler, ReactVegaProps>(function ReactVe
|
|
|
183
204
|
shape: shape ? shape : NULL_FIELD,
|
|
184
205
|
theta: theta ? theta : NULL_FIELD,
|
|
185
206
|
radius: radius ? radius : NULL_FIELD,
|
|
207
|
+
text: text ? text : NULL_FIELD,
|
|
186
208
|
row: rowFacetField,
|
|
187
209
|
column: colFacetField,
|
|
188
210
|
xOffset: NULL_FIELD,
|
|
@@ -199,7 +221,7 @@ const ReactVega = forwardRef<IReactVegaHandler, ReactVegaProps>(function ReactVe
|
|
|
199
221
|
}
|
|
200
222
|
|
|
201
223
|
if (viewPlaceholders.length > 0 && viewPlaceholders[0].current) {
|
|
202
|
-
embed(viewPlaceholders[0].current, spec, { mode: 'vega-lite', actions: showActions, timeFormatLocale: getVegaTimeFormatRules(i18n.language), config:
|
|
224
|
+
embed(viewPlaceholders[0].current, spec, { mode: 'vega-lite', actions: showActions, timeFormatLocale: getVegaTimeFormatRules(i18n.language), config: vegaConfig }).then(res => {
|
|
203
225
|
vegaRefs.current = [res.view];
|
|
204
226
|
try {
|
|
205
227
|
res.view.addEventListener('click', (e) => {
|
|
@@ -247,6 +269,7 @@ const ReactVega = forwardRef<IReactVegaHandler, ReactVegaProps>(function ReactVe
|
|
|
247
269
|
radius: radius ? radius : NULL_FIELD,
|
|
248
270
|
row: rowFacetField,
|
|
249
271
|
column: colFacetField,
|
|
272
|
+
text: text ? text : NULL_FIELD,
|
|
250
273
|
xOffset: NULL_FIELD,
|
|
251
274
|
yOffset: NULL_FIELD,
|
|
252
275
|
details,
|
|
@@ -263,7 +286,7 @@ const ReactVega = forwardRef<IReactVegaHandler, ReactVegaProps>(function ReactVe
|
|
|
263
286
|
ans.params = commonSpec.params;
|
|
264
287
|
}
|
|
265
288
|
if (node) {
|
|
266
|
-
embed(node, ans, { mode: 'vega-lite', actions: showActions, timeFormatLocale: getVegaTimeFormatRules(i18n.language), config:
|
|
289
|
+
embed(node, ans, { mode: 'vega-lite', actions: showActions, timeFormatLocale: getVegaTimeFormatRules(i18n.language), config: vegaConfig }).then(res => {
|
|
267
290
|
vegaRefs.current.push(res.view);
|
|
268
291
|
const paramStores = (res.vgSpec.data?.map(d => d.name) ?? []).filter(
|
|
269
292
|
name => [BRUSH_SIGNAL_NAME, POINT_SIGNAL_NAME].map(p => `${p}_store`).includes(name)
|
|
@@ -350,8 +373,9 @@ const ReactVega = forwardRef<IReactVegaHandler, ReactVegaProps>(function ReactVe
|
|
|
350
373
|
layoutMode,
|
|
351
374
|
width,
|
|
352
375
|
height,
|
|
353
|
-
|
|
354
|
-
details
|
|
376
|
+
vegaConfig,
|
|
377
|
+
details,
|
|
378
|
+
text
|
|
355
379
|
]);
|
|
356
380
|
|
|
357
381
|
useImperativeHandle(ref, () => ({
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import { COUNT_FIELD_ID } from '../../constants';
|
|
2
2
|
import { IViewField } from '../../interfaces';
|
|
3
|
+
import { getMeaAggKey } from '../../utils';
|
|
3
4
|
|
|
4
5
|
export function channelAggregate(encoding: { [key: string]: any }, fields: IViewField[]) {
|
|
5
6
|
Object.values(encoding).forEach((c) => {
|
|
6
7
|
const targetField = fields.find((f) => f.fid === c.field && !('aggregate' in c));
|
|
7
8
|
if (targetField && targetField.fid === COUNT_FIELD_ID) {
|
|
8
9
|
c.title = 'Count';
|
|
10
|
+
c.field = getMeaAggKey(targetField.fid, targetField.aggName)
|
|
9
11
|
} else if (targetField && targetField.analyticType === 'measure') {
|
|
10
12
|
c.title = `${targetField.aggName}(${targetField.name})`;
|
|
13
|
+
c.field = getMeaAggKey(targetField.fid, targetField.aggName)
|
|
11
14
|
}
|
|
12
15
|
});
|
|
13
16
|
}
|
package/src/vis/spec/encode.ts
CHANGED
|
@@ -15,8 +15,12 @@ export interface IEncodeProps {
|
|
|
15
15
|
theta: IViewField;
|
|
16
16
|
radius: IViewField;
|
|
17
17
|
details: Readonly<IViewField[]>;
|
|
18
|
+
text: IViewField;
|
|
18
19
|
}
|
|
19
|
-
function availableChannels(geomType: string): Set<string> {
|
|
20
|
+
export function availableChannels(geomType: string): Set<string> {
|
|
21
|
+
if (geomType === 'text') {
|
|
22
|
+
return new Set(['text', 'color', 'size', 'x', 'y', 'xOffset', 'yOffset', 'opacity']);
|
|
23
|
+
}
|
|
20
24
|
if (geomType === 'arc') {
|
|
21
25
|
return new Set(['opacity', 'color', 'size', 'theta', 'radius']);
|
|
22
26
|
}
|
package/src/vis/spec/view.ts
CHANGED
|
@@ -21,6 +21,7 @@ export function getSingleView(props: SingleViewProps) {
|
|
|
21
21
|
shape,
|
|
22
22
|
theta,
|
|
23
23
|
radius,
|
|
24
|
+
text,
|
|
24
25
|
row,
|
|
25
26
|
column,
|
|
26
27
|
xOffset,
|
|
@@ -31,7 +32,7 @@ export function getSingleView(props: SingleViewProps) {
|
|
|
31
32
|
geomType,
|
|
32
33
|
hideLegend = false,
|
|
33
34
|
} = props;
|
|
34
|
-
const fields: IViewField[] = [x, y, color, opacity, size, shape, row, column, xOffset, yOffset, theta, radius];
|
|
35
|
+
const fields: IViewField[] = [x, y, color, opacity, size, shape, row, column, xOffset, yOffset, theta, radius, text];
|
|
35
36
|
let markType = geomType;
|
|
36
37
|
let config: any = {};
|
|
37
38
|
if (hideLegend) {
|
|
@@ -60,7 +61,8 @@ export function getSingleView(props: SingleViewProps) {
|
|
|
60
61
|
yOffset,
|
|
61
62
|
theta,
|
|
62
63
|
radius,
|
|
63
|
-
details
|
|
64
|
+
details,
|
|
65
|
+
text
|
|
64
66
|
});
|
|
65
67
|
addTooltipEncode(encoding, details)
|
|
66
68
|
if (defaultAggregated) {
|
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
ArrowsUpDownIcon,
|
|
19
19
|
LightBulbIcon,
|
|
20
20
|
CodeBracketSquareIcon,
|
|
21
|
+
Cog6ToothIcon,
|
|
21
22
|
} from '@heroicons/react/24/outline';
|
|
22
23
|
import { observer } from 'mobx-react-lite';
|
|
23
24
|
import React, { SVGProps, useCallback, useMemo } from 'react';
|
|
@@ -155,8 +156,10 @@ const VisualSettings: React.FC<IVisualSettings> = ({ rendererHandler, darkModePr
|
|
|
155
156
|
circle: (props: SVGProps<SVGSVGElement>) => <svg stroke="none" fill="currentColor" strokeWidth="1.5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden {...props}><path strokeLinecap="round" strokeLinejoin="round" d="M6,12 A6,6,0,0,1,18,12 A6,6,0,0,1,6,12" /></svg>,
|
|
156
157
|
tick: (props: SVGProps<SVGSVGElement>) => <svg stroke="currentColor" fill="none" strokeWidth="1.5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden {...props}><path strokeLinecap="round" strokeLinejoin="round" d="M5,12h14" /></svg>,
|
|
157
158
|
rect: (props: SVGProps<SVGSVGElement>) => <svg stroke="none" fill="currentColor" strokeWidth="1.5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden {...props}><path strokeLinecap="round" strokeLinejoin="round" d="M5,5v14h14v-14z" /></svg>,
|
|
159
|
+
text: (props: SVGProps<SVGSVGElement>) => <svg stroke="currentColor" fill="currentColor" strokeWidth="1.5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden {...props}><path strokeLinecap="round" strokeLinejoin="round" d="M10.5 21l5.25-11.25L21 21m-9-3h7.5M3 5.621a48.474 48.474 0 016-.371m0 0c1.12 0 2.233.038 3.334.114M9 5.25V3m3.334 2.364C11.176 10.658 7.69 15.08 3 17.502m9.334-12.138c.896.061 1.785.147 2.666.257m-4.589 8.495a18.023 18.023 0 01-3.827-5.802" /></svg>,
|
|
158
160
|
arc: (props: SVGProps<SVGSVGElement>) => <svg stroke="none" fill="currentColor" strokeWidth="1.5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden {...props}><path strokeLinecap="round" strokeLinejoin="round" d="M12,21l-9,-15a12,12,0,0,1,18,0Z" /></svg>,
|
|
159
161
|
boxplot: (props: SVGProps<SVGSVGElement>) => <svg stroke="currentColor" fill="none" strokeWidth="1.5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden {...props}><path strokeLinecap="round" strokeLinejoin="round" d="M7,7v9h10v-9Zm0,4h8M12,7v-6m-3,0h6M12,16v7m-3,0h6" /></svg>,
|
|
162
|
+
table: (props: SVGProps<SVGSVGElement>) => <svg stroke="currentColor" fill="none" strokeWidth="1.5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden {...props}><path strokeLinecap="round" strokeLinejoin="round" d="M3.375 19.5h17.25m-17.25 0a1.125 1.125 0 01-1.125-1.125M3.375 19.5h7.5c.621 0 1.125-.504 1.125-1.125m-9.75 0V5.625m0 12.75v-1.5c0-.621.504-1.125 1.125-1.125m18.375 2.625V5.625m0 12.75c0 .621-.504 1.125-1.125 1.125m1.125-1.125v-1.5c0-.621-.504-1.125-1.125-1.125m0 3.75h-7.5A1.125 1.125 0 0112 18.375m9.75-12.75c0-.621-.504-1.125-1.125-1.125H3.375c-.621 0-1.125.504-1.125 1.125m19.5 0v1.5c0 .621-.504 1.125-1.125 1.125M2.25 5.625v1.5c0 .621.504 1.125 1.125 1.125m0 0h17.25m-17.25 0h7.5c.621 0 1.125.504 1.125 1.125M3.375 8.25c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125m17.25-3.75h-7.5c-.621 0-1.125.504-1.125 1.125m8.625-1.125c.621 0 1.125.504 1.125 1.125v1.5c0 .621-.504 1.125-1.125 1.125m-17.25 0h7.5m-7.5 0c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125M12 10.875v-1.5m0 1.5c0 .621-.504 1.125-1.125 1.125M12 10.875c0 .621.504 1.125 1.125 1.125m-2.25 0c.621 0 1.125.504 1.125 1.125M13.125 12h7.5m-7.5 0c-.621 0-1.125.504-1.125 1.125M20.625 12c.621 0 1.125.504 1.125 1.125v1.5c0 .621-.504 1.125-1.125 1.125m-17.25 0h7.5M12 14.625v-1.5m0 1.5c0 .621-.504 1.125-1.125 1.125M12 14.625c0 .621.504 1.125 1.125 1.125m-2.25 0c.621 0 1.125.504 1.125 1.125m0 1.5v-1.5m0 0c0-.621.504-1.125 1.125-1.125m0 0h7.5" /></svg>
|
|
160
163
|
}[g],
|
|
161
164
|
})),
|
|
162
165
|
value: markType,
|
|
@@ -278,6 +281,14 @@ const VisualSettings: React.FC<IVisualSettings> = ({ rendererHandler, darkModePr
|
|
|
278
281
|
</FormContainer>
|
|
279
282
|
),
|
|
280
283
|
},
|
|
284
|
+
{
|
|
285
|
+
key: 'config',
|
|
286
|
+
label: 'config',
|
|
287
|
+
icon: Cog6ToothIcon,
|
|
288
|
+
onClick: () => {
|
|
289
|
+
commonStore.setShowVisualConfigPanel(true);
|
|
290
|
+
}
|
|
291
|
+
},
|
|
281
292
|
{
|
|
282
293
|
key: 'export_code',
|
|
283
294
|
label: t('button.export_code'),
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"viewQuery.worker-ffefc111.js","sources":["../src/lib/op/stat.ts","../src/lib/op/aggregate.ts","../src/lib/op/fold.ts","../src/lib/op/bin.ts","../src/lib/viewQuery.ts","../src/workers/viewQuery.worker.js"],"sourcesContent":["export function mean(nums: number[]): number {\n return nums.reduce((a, b) => a + b, 0) / nums.length;\n}\n\nexport function sum(nums: number[]): number {\n return nums.reduce((a, b) => a + b, 0);\n}\n\nexport function median(nums: number[]): number {\n const sorted = nums.sort((a, b) => a - b);\n const mid = Math.floor(sorted.length / 2);\n return sorted.length % 2 === 0 ? (sorted[mid] + sorted[mid - 1]) / 2 : sorted[mid];\n}\n\nexport function variance(nums: number[]): number {\n const m = mean(nums);\n return mean(nums.map((x) => (x - m) ** 2));\n}\n\nexport function stdev(nums: number[]): number {\n return Math.sqrt(variance(nums));\n}\n\nexport function max(nums: number[]): number {\n let ans = -Infinity;\n for (let n of nums) {\n if (n > ans) {\n ans = n;\n }\n }\n return ans;\n}\n\nexport function min(nums: number[]): number {\n let ans = Infinity;\n for (let n of nums) {\n if (n < ans) {\n ans = n;\n }\n }\n return ans;\n}\n\nexport function count(nums: number[]): number {\n return nums.length;\n}\n","import { IRow } from \"../../interfaces\";\nimport { IAggQuery } from \"../interfaces\";\nimport { sum, mean, median, stdev, variance, max, min, count } from \"./stat\";\n\nconst aggregatorMap = {\n sum,\n mean,\n median,\n stdev,\n variance,\n max,\n min,\n count,\n};\n\nconst KEY_JOINER = '___';\n\nexport function aggregate (data: IRow[], query: IAggQuery): IRow[] {\n const { groupBy, agg } = query;\n const ans: Map<string, IRow> = new Map();\n const groups: Map<string, IRow[]> = new Map();\n for (let row of data) {\n const gk = groupBy.map((k) => row[k]).join(KEY_JOINER);\n\n if (!groups.has(gk)) {\n groups.set(gk, []);\n }\n groups.get(gk)?.push(row);\n }\n for (let [gk, subGroup] of groups) {\n if (subGroup.length === 0) {\n continue;\n }\n let aggRow: IRow = {};\n for (let k of groupBy) {\n aggRow[k] = subGroup[0][k];\n }\n for (let meaKey in agg) {\n if (aggRow[meaKey] === undefined) {\n aggRow[meaKey] = 0;\n }\n const values: number[] = subGroup.map((r) => r[meaKey]) ?? [];\n const aggregator = aggregatorMap[agg[meaKey]] ?? sum;\n aggRow[meaKey] = aggregator(values);\n }\n ans.set(gk, aggRow);\n }\n return Array.from(ans.values());\n}","import { IRow } from \"../../interfaces\";\nimport { IFoldQuery } from \"../interfaces\";\n\nexport function fold (data: IRow[], query: IFoldQuery): IRow[] {\n const { foldBy, newFoldKeyCol, newFoldValueCol } = query;\n const ans: IRow[] = [];\n for (let row of data) {\n for (let k of foldBy) {\n const newRow = { ...row };\n newRow[newFoldKeyCol] = k;\n newRow[newFoldValueCol] = row[k];\n delete newRow[k];\n ans.push(newRow);\n }\n }\n return ans;\n}","import { IRow } from \"../../interfaces\";\nimport { IBinQuery } from \"../interfaces\";\n\nexport function bin (dataSource: IRow[], query: IBinQuery): IRow[] {\n const { binBy, newBinCol, binSize } = query;\n let _min = Infinity;\n let _max = -Infinity;\n for (let i = 0; i < dataSource.length; i++) {\n let val = dataSource[i][binBy];\n if (val > _max) _max = val;\n if (val < _min) _min = val;\n }\n const step = (_max - _min) / binSize;\n // const beaStep = Math.max(-Math.round(Math.log10(_max - _min)) + 2, 0)\n return dataSource.map((r) => {\n let bIndex = Math.floor((r[binBy] - _min) / step);\n if (bIndex === binSize) bIndex = binSize - 1;\n return {\n ...r,\n [newBinCol]: [bIndex * step + _min, (bIndex + 1) * step + _min],\n \n // [binFid]: Number(((bIndex * step + _min)).toFixed(beaStep)),\n };\n });\n}","import { IMutField, IRow } from \"../interfaces\";\nimport { aggregate } from \"./op/aggregate\";\nimport { fold } from \"./op/fold\";\nimport { IAggQuery, IBinQuery, IFoldQuery, IRawQuery } from \"./interfaces\";\nimport { bin } from \"./op/bin\";\n\nexport type IViewQuery = IAggQuery | IFoldQuery | IBinQuery | IRawQuery;\n\nexport function queryView (rawData: IRow[], metas: IMutField[], query: IViewQuery) {\n switch (query.op) {\n case 'aggregate':\n return aggregate(rawData, query);\n case 'fold':\n return fold(rawData, query);\n case 'bin':\n return bin(rawData, query);\n case 'raw':\n default:\n return rawData;\n }\n\n}","import { queryView } from '../lib/viewQuery'\nconst main = e => {\n try {\n const { dataSource, metas, query } = e.data;\n const ans = queryView(dataSource, metas, query);\n self.postMessage(ans);\n\n } catch (err) {\n // console.log(err.s)\n // log err stack\n console.error(err.stack);\n self.postMessage(err.stack);\n }\n};\n\nself.addEventListener('message', main, false);\n"],"names":["mean","nums","a","b","sum","median","sorted","mid","variance","m","x","stdev","max","ans","n","min","count","aggregatorMap","KEY_JOINER","aggregate","data","query","groupBy","agg","groups","row","gk","k","_a","subGroup","aggRow","meaKey","values","r","aggregator","fold","foldBy","newFoldKeyCol","newFoldValueCol","newRow","bin","dataSource","binBy","newBinCol","binSize","_min","_max","i","val","step","bIndex","queryView","rawData","metas","main","e","err"],"mappings":"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"}
|