@rokkit/data 1.0.0-next.147 → 1.0.0-next.150
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/benchmark/fixtures.d.ts +33 -0
- package/dist/benchmark/index.d.ts +2 -0
- package/dist/benchmark/runner.d.ts +10 -0
- package/dist/{constants.d.ts → src/constants.d.ts} +6 -7
- package/dist/{dataset.d.ts → src/dataset.d.ts} +33 -15
- package/dist/src/dataset.svelte.d.ts +79 -0
- package/dist/{index.d.ts → src/index.d.ts} +1 -1
- package/dist/{infer.d.ts → src/infer.d.ts} +39 -0
- package/dist/{model.d.ts → src/model.d.ts} +1 -1
- package/dist/src/pipeline.d.ts +8 -0
- package/dist/{rollup.d.ts → src/rollup.d.ts} +2 -12
- package/package.json +1 -1
- package/src/constants.js +9 -4
- package/src/dataset.js +148 -119
- package/src/dataset.svelte.js +181 -0
- package/src/formatter.js +1 -1
- package/src/index.js +9 -1
- package/src/infer.js +103 -2
- package/src/join.js +11 -6
- package/src/model.js +3 -3
- package/src/pipeline.js +97 -0
- package/src/renamer.js +8 -1
- package/src/rollup.js +59 -62
- package/src/view.js +1 -2
- /package/dist/{aggregators.d.ts → src/aggregators.d.ts} +0 -0
- /package/dist/{convert.d.ts → src/convert.d.ts} +0 -0
- /package/dist/{filter.d.ts → src/filter.d.ts} +0 -0
- /package/dist/{formatter.d.ts → src/formatter.d.ts} +0 -0
- /package/dist/{hierarchy.d.ts → src/hierarchy.d.ts} +0 -0
- /package/dist/{join.d.ts → src/join.d.ts} +0 -0
- /package/dist/{list.d.ts → src/list.d.ts} +0 -0
- /package/dist/{metadata.d.ts → src/metadata.d.ts} +0 -0
- /package/dist/{parser.d.ts → src/parser.d.ts} +0 -0
- /package/dist/{renamer.d.ts → src/renamer.d.ts} +0 -0
- /package/dist/{types.d.ts → src/types.d.ts} +0 -0
- /package/dist/{utils.d.ts → src/utils.d.ts} +0 -0
- /package/dist/{view.d.ts → src/view.d.ts} +0 -0
package/src/infer.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { ascending, descending } from 'd3-array'
|
|
2
2
|
import { compact } from '@rokkit/core'
|
|
3
|
-
import { omit } from 'ramda'
|
|
4
3
|
import { createFormatter } from './formatter'
|
|
5
4
|
import { defaultViewOptions, defaultActionOrder } from './constants'
|
|
6
5
|
import { typeOf } from './utils'
|
|
@@ -101,7 +100,7 @@ export function getSample(data, deepScan = true) {
|
|
|
101
100
|
return data.reduce(
|
|
102
101
|
(acc, cur) => ({
|
|
103
102
|
...acc,
|
|
104
|
-
...compact(
|
|
103
|
+
...compact(Object.fromEntries(Object.entries(cur).filter(([k]) => !(k in acc))))
|
|
105
104
|
}),
|
|
106
105
|
{}
|
|
107
106
|
)
|
|
@@ -274,3 +273,105 @@ export function deriveMetadata(dataArray, options = {}) {
|
|
|
274
273
|
|
|
275
274
|
return columns
|
|
276
275
|
}
|
|
276
|
+
|
|
277
|
+
// ── Scale inference ──────────────────────────────────────────────────────────
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Infers whether a column's values are discrete (categorical) or continuous (quantitative).
|
|
281
|
+
*
|
|
282
|
+
* Rules:
|
|
283
|
+
* - string, boolean → always discrete
|
|
284
|
+
* - date, number (float) → always continuous
|
|
285
|
+
* - integer → discrete when ≤20 unique values OR unique ratio < 5 %,
|
|
286
|
+
* continuous otherwise (e.g. large ID column)
|
|
287
|
+
* - anything else → discrete (safe default for unknown types)
|
|
288
|
+
*
|
|
289
|
+
* @param {any[]} values - All values for the column (may include nulls).
|
|
290
|
+
* @returns {'discrete'|'continuous'}
|
|
291
|
+
*/
|
|
292
|
+
function inferIntegerScale(nonNull) {
|
|
293
|
+
const unique = new Set(nonNull).size
|
|
294
|
+
return unique <= 20 || unique / nonNull.length < 0.05 ? 'discrete' : 'continuous'
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
const SCALE_BY_TYPE = {
|
|
298
|
+
string: () => 'discrete',
|
|
299
|
+
boolean: () => 'discrete',
|
|
300
|
+
date: () => 'continuous',
|
|
301
|
+
number: () => 'continuous',
|
|
302
|
+
integer: (nonNull) => inferIntegerScale(nonNull)
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
export function inferScale(values) {
|
|
306
|
+
const nonNull = values.filter((v) => v !== null && v !== undefined)
|
|
307
|
+
if (nonNull.length === 0) return 'discrete'
|
|
308
|
+
const type = typeOf(nonNull[0])
|
|
309
|
+
return (SCALE_BY_TYPE[type] ?? (() => 'discrete'))(nonNull)
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Adds a `scale` property to each column definition.
|
|
314
|
+
*
|
|
315
|
+
* @param {Array<Object>} columns - Column definitions (from deriveColumns / deriveMetadata).
|
|
316
|
+
* @param {any[]} data - Source rows.
|
|
317
|
+
* @returns {Array<Object>} Column definitions with `scale` added.
|
|
318
|
+
*/
|
|
319
|
+
export function addScales(columns, data) {
|
|
320
|
+
return columns.map((col) => ({
|
|
321
|
+
...col,
|
|
322
|
+
scale: inferScale(data.map((r) => r[col.name]))
|
|
323
|
+
}))
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Merges user-provided enhancements into auto-derived column definitions.
|
|
328
|
+
* Enhancements are matched by `name` and merged (user values win).
|
|
329
|
+
* Enhancements for unknown column names are appended as synthetic columns.
|
|
330
|
+
*
|
|
331
|
+
* @param {Array<Object>} derived - Auto-derived column definitions.
|
|
332
|
+
* @param {Array<Object>} enhancements - User-provided overrides/additions.
|
|
333
|
+
* @returns {Array<Object>} Merged column definitions.
|
|
334
|
+
*/
|
|
335
|
+
export function mergeColumnEnhancements(derived, enhancements) {
|
|
336
|
+
const enhMap = new Map(enhancements.map((e) => [e.name, e]))
|
|
337
|
+
const result = derived.map((col) => {
|
|
338
|
+
const enh = enhMap.get(col.name)
|
|
339
|
+
return enh ? { ...col, ...enh } : col
|
|
340
|
+
})
|
|
341
|
+
const derivedNames = new Set(derived.map((c) => c.name))
|
|
342
|
+
for (const e of enhancements) {
|
|
343
|
+
if (!derivedNames.has(e.name)) result.push(e)
|
|
344
|
+
}
|
|
345
|
+
return result
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* Full column definition pipeline: derive → format → scale → merge enhancements.
|
|
350
|
+
*
|
|
351
|
+
* Produces column descriptors suitable for use in Table, TreeTable, and chart
|
|
352
|
+
* components. Each column gets: name, type, scale, sortable, filterable, fields,
|
|
353
|
+
* formatter — plus any user-supplied properties from `enhancements`.
|
|
354
|
+
*
|
|
355
|
+
* @param {any[]} data - Source rows.
|
|
356
|
+
* @param {Object} [options] - Options forwarded to deriveColumns / addFormatters.
|
|
357
|
+
* @param {Array<Object>} [options.enhancements=[]] - Per-column overrides keyed by name.
|
|
358
|
+
* Use to override scale, add a label, attach a custom formatter, etc.
|
|
359
|
+
* @param {string} [options.language='en-US'] - Locale for formatters.
|
|
360
|
+
* @param {string} [options.scanMode='fast'] - 'fast' (first row) or 'deep' (all rows).
|
|
361
|
+
* @returns {Array<Object>} Column definitions with scale and formatters.
|
|
362
|
+
*/
|
|
363
|
+
export function deriveColumnDefs(data, options = {}) {
|
|
364
|
+
const { enhancements = [], language, scanMode } = { ...defaultViewOptions, ...options }
|
|
365
|
+
|
|
366
|
+
if (data.length === 0) return enhancements
|
|
367
|
+
|
|
368
|
+
let columns = deriveColumns(data, { scanMode })
|
|
369
|
+
columns = addFormatters(columns, language)
|
|
370
|
+
columns = addScales(columns, data)
|
|
371
|
+
|
|
372
|
+
if (enhancements.length > 0) {
|
|
373
|
+
columns = mergeColumnEnhancements(columns, enhancements)
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
return columns
|
|
377
|
+
}
|
package/src/join.js
CHANGED
|
@@ -13,14 +13,19 @@
|
|
|
13
13
|
* @returns {Array<Object>} - An object with the inner and outer join result.
|
|
14
14
|
*/
|
|
15
15
|
function joinData(first, second, condition) {
|
|
16
|
-
|
|
16
|
+
const inner = []
|
|
17
17
|
const outer = []
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
19
|
+
for (const f of first) {
|
|
20
|
+
let matched = false
|
|
21
|
+
for (const s of second) {
|
|
22
|
+
if (condition(f, s)) {
|
|
23
|
+
inner.push({ ...s, ...f })
|
|
24
|
+
matched = true
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
if (!matched) outer.push(f)
|
|
28
|
+
}
|
|
24
29
|
return { inner, outer }
|
|
25
30
|
}
|
|
26
31
|
|
package/src/model.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
const copy = (val) => structuredClone(val)
|
|
2
2
|
import { getSample } from './infer'
|
|
3
3
|
import { typeOf } from './utils'
|
|
4
4
|
|
|
@@ -67,8 +67,8 @@ export function model() {
|
|
|
67
67
|
* Renames the reference names using a renamer
|
|
68
68
|
* @param {Function} rename - the renamer function
|
|
69
69
|
*/
|
|
70
|
-
renameUsing: (rename
|
|
71
|
-
if (rename
|
|
70
|
+
renameUsing: (rename) => {
|
|
71
|
+
if (rename) {
|
|
72
72
|
data = data.map((x) => ({ ...x, name: rename(x.name) }))
|
|
73
73
|
}
|
|
74
74
|
return actions
|
package/src/pipeline.js
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared pipeline execution logic used by both DataSet and ReactiveDataSet.
|
|
3
|
+
*
|
|
4
|
+
* Kept in a plain `.js` file so it can be imported from both regular modules
|
|
5
|
+
* and `.svelte.js` files without triggering rune compilation errors.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { deriveSortableColumn } from './infer.js'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Sort an array in-place by one or more field specs.
|
|
12
|
+
* @param {any[]} data - Array to sort (mutated in place).
|
|
13
|
+
* @param {...string|Object|Array} fields - Sort field specs (same as DataSet.sortBy).
|
|
14
|
+
* @returns {any[]}
|
|
15
|
+
*/
|
|
16
|
+
export function sortDataByFields(data, ...fields) {
|
|
17
|
+
const sorters = fields.map(deriveSortableColumn)
|
|
18
|
+
data.sort((a, b) => {
|
|
19
|
+
let result = 0
|
|
20
|
+
for (let i = 0; i < sorters.length && result === 0; i++) {
|
|
21
|
+
const { name, sorter } = sorters[i]
|
|
22
|
+
result = sorter(a[name], b[name])
|
|
23
|
+
}
|
|
24
|
+
return result
|
|
25
|
+
})
|
|
26
|
+
return data
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Execute a list of pipeline ops in a single fused pass over `data`.
|
|
31
|
+
*
|
|
32
|
+
* Ops:
|
|
33
|
+
* { type: 'filter', fn } — keep rows where fn(row) is truthy
|
|
34
|
+
* { type: 'map', fn } — transform row via fn(row)
|
|
35
|
+
* { type: 'sort', fields } — sort the result by fields
|
|
36
|
+
*
|
|
37
|
+
* Consecutive filter/map ops are merged into one loop.
|
|
38
|
+
* Sort ops are applied after the linear pass.
|
|
39
|
+
*
|
|
40
|
+
* @param {any[]} data
|
|
41
|
+
* @param {Array<{type:string, fn?:Function, fields?:string[]}>} ops
|
|
42
|
+
* @returns {any[]}
|
|
43
|
+
*/
|
|
44
|
+
function applyOpsToRow(row, linearOps) {
|
|
45
|
+
let cur = row
|
|
46
|
+
for (const op of linearOps) {
|
|
47
|
+
if (op.type === 'filter') {
|
|
48
|
+
if (!op.fn(cur)) return null
|
|
49
|
+
} else {
|
|
50
|
+
cur = op.fn(cur)
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return cur
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function applyLinearOps(data, linearOps) {
|
|
57
|
+
const out = []
|
|
58
|
+
for (const row of data) {
|
|
59
|
+
const result = applyOpsToRow(row, linearOps)
|
|
60
|
+
if (result !== null) out.push(result)
|
|
61
|
+
}
|
|
62
|
+
return out
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function collectLinearOps(ops, i) {
|
|
66
|
+
const linearOps = []
|
|
67
|
+
while (i < ops.length && ops[i].type !== 'sort') linearOps.push(ops[i++])
|
|
68
|
+
return { linearOps, i }
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function collectSortFields(ops, i) {
|
|
72
|
+
const sortFields = []
|
|
73
|
+
while (i < ops.length && ops[i].type === 'sort') sortFields.push(...ops[i++].fields)
|
|
74
|
+
return { sortFields, i }
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function executeFused(data, ops) {
|
|
78
|
+
if (ops.length === 0) return data
|
|
79
|
+
|
|
80
|
+
let result = data
|
|
81
|
+
let i = 0
|
|
82
|
+
|
|
83
|
+
while (i < ops.length) {
|
|
84
|
+
const linear = collectLinearOps(ops, i)
|
|
85
|
+
i = linear.i
|
|
86
|
+
if (linear.linearOps.length > 0) result = applyLinearOps(result, linear.linearOps)
|
|
87
|
+
|
|
88
|
+
const sorted = collectSortFields(ops, i)
|
|
89
|
+
i = sorted.i
|
|
90
|
+
if (sorted.sortFields.length > 0) {
|
|
91
|
+
result = [...result]
|
|
92
|
+
sortDataByFields(result, ...sorted.sortFields)
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return result
|
|
97
|
+
}
|
package/src/renamer.js
CHANGED
package/src/rollup.js
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { omit, pick, mergeLeft, map, difference, uniq, pipe } from 'ramda'
|
|
2
|
-
|
|
3
1
|
/**
|
|
4
2
|
* Sets initial values for summaries.
|
|
5
3
|
*
|
|
@@ -28,7 +26,7 @@ export function addToSummaries(group, row, summaries) {
|
|
|
28
26
|
}
|
|
29
27
|
|
|
30
28
|
/**
|
|
31
|
-
* Groups data by specified keys.
|
|
29
|
+
* Groups data by specified keys using a composite string key (Phase 3: replaces JSON.stringify).
|
|
32
30
|
*
|
|
33
31
|
* @param {Array} data - An array of data points.
|
|
34
32
|
* @param {Array} groupByKeys - Keys to group the data by.
|
|
@@ -36,17 +34,22 @@ export function addToSummaries(group, row, summaries) {
|
|
|
36
34
|
* @returns {Object} Grouped data object with aggregation placeholders.
|
|
37
35
|
*/
|
|
38
36
|
export function groupDataByKeys(data, groupByKeys, summaries) {
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
37
|
+
const groupedData = new Map()
|
|
38
|
+
|
|
39
|
+
for (const row of data) {
|
|
40
|
+
// Composite key: avoids JSON.stringify overhead
|
|
41
|
+
const key = groupByKeys.map((k) => row[k]).join('\x00')
|
|
42
|
+
|
|
43
|
+
if (!groupedData.has(key)) {
|
|
44
|
+
const group = {}
|
|
45
|
+
for (const k of groupByKeys) group[k] = row[k]
|
|
46
|
+
Object.assign(group, initialValues(summaries))
|
|
47
|
+
groupedData.set(key, group)
|
|
44
48
|
}
|
|
45
|
-
addToSummaries(
|
|
46
|
-
|
|
47
|
-
}, {})
|
|
49
|
+
addToSummaries(groupedData.get(key), row, summaries)
|
|
50
|
+
}
|
|
48
51
|
|
|
49
|
-
return
|
|
52
|
+
return [...groupedData.values()]
|
|
50
53
|
}
|
|
51
54
|
|
|
52
55
|
/**
|
|
@@ -57,9 +60,8 @@ export function groupDataByKeys(data, groupByKeys, summaries) {
|
|
|
57
60
|
* @returns {Array} Aligned data array.
|
|
58
61
|
*/
|
|
59
62
|
export function fillAlignedData(groupedData, config, fillRowsFunc) {
|
|
60
|
-
// const fillRowsFunc = getAlignGenerator(df.data, config)
|
|
61
63
|
const { actual_flag, children } = config
|
|
62
|
-
return
|
|
64
|
+
return groupedData.map((row) => ({
|
|
63
65
|
...row,
|
|
64
66
|
[children]: [
|
|
65
67
|
...row[children].map((value) => ({ ...value, [actual_flag]: 1 })),
|
|
@@ -68,6 +70,49 @@ export function fillAlignedData(groupedData, config, fillRowsFunc) {
|
|
|
68
70
|
}))
|
|
69
71
|
}
|
|
70
72
|
|
|
73
|
+
/**
|
|
74
|
+
* Creates a generator that produces missing rows in a dataset based on specified columns.
|
|
75
|
+
*
|
|
76
|
+
* @param {Array<Object>} data - The array of objects representing the dataset.
|
|
77
|
+
* @param {Object} config - The configuration object.
|
|
78
|
+
* @returns {Function} A generator function that when called, produces the missing rows.
|
|
79
|
+
*/
|
|
80
|
+
function buildAlignTemplate(config) {
|
|
81
|
+
const { align_by, group_by, actual_flag } = config
|
|
82
|
+
const omitKeys = new Set([...align_by, ...group_by])
|
|
83
|
+
const template = { [actual_flag]: 0 }
|
|
84
|
+
for (const [k, v] of Object.entries(config.template)) {
|
|
85
|
+
if (!omitKeys.has(k)) template[k] = v
|
|
86
|
+
}
|
|
87
|
+
return template
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function collectAllCombos(data, align_by) {
|
|
91
|
+
const seen = new Map()
|
|
92
|
+
for (const row of data) {
|
|
93
|
+
const key = align_by.map((k) => row[k]).join('\x00')
|
|
94
|
+
if (!seen.has(key)) {
|
|
95
|
+
const combo = {}
|
|
96
|
+
for (const k of align_by) combo[k] = row[k]
|
|
97
|
+
seen.set(key, combo)
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return [...seen.values()]
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export function getAlignGenerator(data, config) {
|
|
104
|
+
const { align_by } = config
|
|
105
|
+
const template = buildAlignTemplate(config)
|
|
106
|
+
const allCombos = collectAllCombos(data, align_by)
|
|
107
|
+
|
|
108
|
+
return (children) => {
|
|
109
|
+
const childKeys = new Set(children.map((c) => align_by.map((k) => c[k]).join('\x00')))
|
|
110
|
+
return allCombos
|
|
111
|
+
.filter((combo) => !childKeys.has(align_by.map((k) => combo[k]).join('\x00')))
|
|
112
|
+
.map((combo) => ({ ...combo, ...template }))
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
71
116
|
/**
|
|
72
117
|
* Performs aggregation operations on grouped data.
|
|
73
118
|
*
|
|
@@ -88,51 +133,3 @@ export function aggregateData(dataArray, summaries) {
|
|
|
88
133
|
)
|
|
89
134
|
}))
|
|
90
135
|
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Creates a generator that produces missing rows in a dataset based on specified columns.
|
|
94
|
-
* The function determines all unique combinations of the specified columns in config.align_by
|
|
95
|
-
* and returns a generator function to create the missing combinations, potentially with default
|
|
96
|
-
* values for other columns.
|
|
97
|
-
* @param {Array<Object>} data - The array of objects representing the dataset.
|
|
98
|
-
* @param {Object} config - The configuration object.
|
|
99
|
-
*
|
|
100
|
-
* @returns {Function} A generator function that when called, produces the missing rows.
|
|
101
|
-
*/
|
|
102
|
-
export function getAlignGenerator(data, config) {
|
|
103
|
-
const { align_by, group_by, actual_flag } = config
|
|
104
|
-
const template = { ...omit([...align_by, ...group_by], config.template), [actual_flag]: 0 }
|
|
105
|
-
const subset = pipe(map(pick(align_by)), uniq)(data)
|
|
106
|
-
|
|
107
|
-
return pipe(map(pick(align_by)), uniq, difference(subset), map(mergeLeft(template)))
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Returns an aggregator object with a mapper and reducer function.
|
|
112
|
-
*
|
|
113
|
-
* @param {Array<string>} from - The key or keys to aggregate.
|
|
114
|
-
* @param {Function} using - The aggregation function.
|
|
115
|
-
* @returns {import('./types').SummaryConfig} - An object with a mapper and reducer function.
|
|
116
|
-
*/
|
|
117
|
-
// export function getAggregator(from, into, using = identity) {
|
|
118
|
-
// // const mapper = pick(Array.isArray ? from : [from])
|
|
119
|
-
// return {
|
|
120
|
-
// mapper: pick(from),
|
|
121
|
-
// reducers: [{ field: into, formula: using }]
|
|
122
|
-
// }
|
|
123
|
-
// }
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* Returns the default aggregator which rolls up the columns other than the group_by columns into a single object.
|
|
127
|
-
*
|
|
128
|
-
* @param {import('./types').Metadata} metadata - The metadata for the columns to be aggregated.
|
|
129
|
-
* @param {Object} config - The configuration used to build the aggregator.
|
|
130
|
-
*
|
|
131
|
-
* @returns {Object} An object containing the default aggregator for the specified metadata and configuration.
|
|
132
|
-
*/
|
|
133
|
-
// export function defaultAggregator(metadata, config) {
|
|
134
|
-
// const child = metadata.filter((col) => !config.group_by.includes(col.name))
|
|
135
|
-
// const keys = child.map((col) => col.name)
|
|
136
|
-
|
|
137
|
-
// return { ...getAggregator(keys, config.children), metadata: child }
|
|
138
|
-
// }
|
package/src/view.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { omit } from 'ramda'
|
|
2
1
|
import { get, writable } from 'svelte/store'
|
|
3
2
|
import { deriveMetadata, deriveSortableColumn } from './infer'
|
|
4
3
|
|
|
@@ -162,7 +161,7 @@ export function dataview(data, options) {
|
|
|
162
161
|
let sortGroup = []
|
|
163
162
|
|
|
164
163
|
return {
|
|
165
|
-
...
|
|
164
|
+
...Object.fromEntries(Object.entries(store).filter(([k]) => k !== 'set' && k !== 'update')),
|
|
166
165
|
// filter: noop,
|
|
167
166
|
/**
|
|
168
167
|
* Clears the applied sort order from the hierarchy.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|