@rokkit/data 1.0.0-next.94
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/LICENSE +21 -0
- package/README.md +50 -0
- package/package.json +56 -0
- package/src/aggregators.js +24 -0
- package/src/constants.js +72 -0
- package/src/convert.js +36 -0
- package/src/dataset.js +442 -0
- package/src/filter.js +57 -0
- package/src/formatter.js +56 -0
- package/src/hierarchy.js +136 -0
- package/src/index.js +6 -0
- package/src/infer.js +263 -0
- package/src/list.js +232 -0
- package/src/metadata.js +106 -0
- package/src/model.js +100 -0
- package/src/parser.js +110 -0
- package/src/renamer.js +98 -0
- package/src/rollup.js +138 -0
- package/src/types.js +208 -0
- package/src/utils.js +31 -0
- package/src/view.js +187 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2022 Jerry Thomas
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# @rokkit/data
|
|
2
|
+
|
|
3
|
+
This package provides a set of tools for managing and manipulating data in user interfaces. It is framework agnostic and can be used with any ui framework.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Datasets:** Manage and manipulate datasets with ease
|
|
8
|
+
- filtering, sorting, and aggregation.
|
|
9
|
+
- **Joins:** Combine datasets effortlessly with support for inner, outer, left, and right joins.
|
|
10
|
+
- **Rollup:** Summarize data across multiple dimensions, calculating aggregate statistics like sum, average, min, and max.
|
|
11
|
+
- **Modeling:** Create and manage data models, including merging, renaming, and resolving conflicts.
|
|
12
|
+
- **Renaming:** Simplify key renaming in JavaScript objects, with options for prefixes, suffixes, and custom separators.
|
|
13
|
+
- **Dataviews:** Create interactive views for exploring and analyzing datasets, including sortable and filterable columns.
|
|
14
|
+
|
|
15
|
+
## Dataset
|
|
16
|
+
|
|
17
|
+
- The `dataset` function initializes a dataset from an array of objects.
|
|
18
|
+
- This dataset comprises data rows that are sortable, filterable, and groupable.
|
|
19
|
+
- Leverage dataset for SQL-like operations such as selecting, updating, and deleting rows.
|
|
20
|
+
- Employ aggregate functions like sum, average, and count for summarizing multiple attributes of the data.
|
|
21
|
+
- Utilize the dataset for various data operations like joining and merging data from disparate sources.
|
|
22
|
+
- Establish connected data views with joins to visualize data relationships, particularly for tracking parent-child connections.
|
|
23
|
+
|
|
24
|
+
This makes it easier to build a tweenable data structure for animations. Here is an example of how to use the `dataset` to generate a tweenable data:
|
|
25
|
+
|
|
26
|
+
```js
|
|
27
|
+
function tweenable(data, by, group, template) {
|
|
28
|
+
return dataset(data)
|
|
29
|
+
.groupBy(by)
|
|
30
|
+
.using(template)
|
|
31
|
+
.alignBy(...group)
|
|
32
|
+
.rollup()
|
|
33
|
+
.sortBy(by)
|
|
34
|
+
.select()
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Refer to [dataset](docs/dataset.md) documentation for more details.
|
|
39
|
+
|
|
40
|
+
## DataView
|
|
41
|
+
|
|
42
|
+
- Utilize the `dataview` function to create a data view, enabling dynamic data manipulation and observation.
|
|
43
|
+
- This view facilitates sorting, filtering, and grouping data while providing insight into selected or hidden rows.
|
|
44
|
+
- The original dataset remains untouched while the view offers flexible data presentation options.
|
|
45
|
+
- Associate actions such as select, edit, and delete with data rows using action columns within the view.
|
|
46
|
+
- Manage data effectively, including parent-child links, even within a flat array structure.
|
|
47
|
+
|
|
48
|
+
Refer to [dataview](docs/dataview.md) documentation for more details.
|
|
49
|
+
|
|
50
|
+
The `dataview` function initializes a manageable data state with methods that allow for manipulation and observation of data changes, integrating smoothly with UI updates.
|
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@rokkit/data",
|
|
3
|
+
"version": "1.0.0-next.94",
|
|
4
|
+
"description": "Contains generic data manipulation functions that can be used in various components.",
|
|
5
|
+
"author": "Jerry Thomas <me@jerrythomas.name>",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"main": "index.js",
|
|
8
|
+
"module": "src/index.js",
|
|
9
|
+
"types": "dist/index.d.ts",
|
|
10
|
+
"type": "module",
|
|
11
|
+
"publishConfig": {
|
|
12
|
+
"access": "public"
|
|
13
|
+
},
|
|
14
|
+
"devDependencies": {
|
|
15
|
+
"@sveltejs/vite-plugin-svelte": "^3.0.2",
|
|
16
|
+
"@testing-library/svelte": "^4.1.0",
|
|
17
|
+
"@types/ramda": "^0.29.12",
|
|
18
|
+
"@vitest/coverage-v8": "^1.4.0",
|
|
19
|
+
"@vitest/ui": "~1.4.0",
|
|
20
|
+
"typescript": "^5.4.4",
|
|
21
|
+
"vite": "^5.2.8",
|
|
22
|
+
"vitest": "~1.4.0",
|
|
23
|
+
"shared-config": "1.0.0-next.94"
|
|
24
|
+
},
|
|
25
|
+
"files": [
|
|
26
|
+
"src/**/*.js",
|
|
27
|
+
"src/**/*.svelte"
|
|
28
|
+
],
|
|
29
|
+
"exports": {
|
|
30
|
+
"./src": "./src",
|
|
31
|
+
"./package.json": "./package.json",
|
|
32
|
+
".": {
|
|
33
|
+
"types": "./dist/index.d.ts",
|
|
34
|
+
"import": "./src/index.js",
|
|
35
|
+
"svelte": "./src/index.js"
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"@lukeed/uuid": "^2.0.1",
|
|
40
|
+
"d3-array": "^3.2.4",
|
|
41
|
+
"d3-collection": "^1.0.7",
|
|
42
|
+
"ramda": "^0.29.1",
|
|
43
|
+
"svelte": "^4.2.12",
|
|
44
|
+
"@rokkit/core": "1.0.0-next.94"
|
|
45
|
+
},
|
|
46
|
+
"scripts": {
|
|
47
|
+
"format": "prettier --write .",
|
|
48
|
+
"lint": "eslint --fix .",
|
|
49
|
+
"test:ci": "vitest run",
|
|
50
|
+
"test:ui": "vitest --ui",
|
|
51
|
+
"test": "vitest",
|
|
52
|
+
"coverage": "vitest run --coverage",
|
|
53
|
+
"latest": "pnpm upgrade --latest && pnpm test:ci",
|
|
54
|
+
"release": "pnpm publish --access public"
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Counts the number of values in an array.
|
|
3
|
+
*
|
|
4
|
+
* @param {Array} values - An array of values to count.
|
|
5
|
+
* @returns {number} The count of values in the array.
|
|
6
|
+
*/
|
|
7
|
+
export const counter = (values) => values.length
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Calculates the quartiles and interquartile range (IQR) of a numeric data array.
|
|
11
|
+
* Assumes that the `quantile` function is defined elsewhere and can calculate a
|
|
12
|
+
* quantile for a given array of numbers and a probability.
|
|
13
|
+
*
|
|
14
|
+
* @param {number[]} values - An array of numeric values to calculate the quartiles for.
|
|
15
|
+
* @returns {Object} An object containing the first quartile (q1), third quartile (q3),
|
|
16
|
+
* interquartile range (iqr), and the minimum and maximum range values (qr_min, qr_max)
|
|
17
|
+
* after applying the IQR rule for identifying potential outliers.
|
|
18
|
+
*/
|
|
19
|
+
export const violin = (values) => {
|
|
20
|
+
const { q1, q3 } = values
|
|
21
|
+
const iqr = q3 - q1
|
|
22
|
+
|
|
23
|
+
return { ...values, q1, q3, iqr, qr_min: q1 - 1.5 * iqr, qr_max: q1 + 1.5 * iqr }
|
|
24
|
+
}
|
package/src/constants.js
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { identity, pick } from 'ramda'
|
|
2
|
+
|
|
3
|
+
export const pickAllowedConfig = pick(['children', 'actual_flag'])
|
|
4
|
+
|
|
5
|
+
/** @type {import('./types').DataFrameConfig */
|
|
6
|
+
export const defaultConfig = {
|
|
7
|
+
children: 'children',
|
|
8
|
+
actual_flag: 'actual_flag',
|
|
9
|
+
inplace: false,
|
|
10
|
+
group_by: [],
|
|
11
|
+
align_by: [],
|
|
12
|
+
template: {},
|
|
13
|
+
summaries: []
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const defaultPathOptions = {
|
|
17
|
+
path: null,
|
|
18
|
+
separator: '/',
|
|
19
|
+
currencySuffix: '_currency'
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const defaultViewOptions = {
|
|
23
|
+
...defaultPathOptions,
|
|
24
|
+
expanded: false,
|
|
25
|
+
actions: [],
|
|
26
|
+
language: 'en-US',
|
|
27
|
+
scanMode: 'fast'
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export const defaultActionOrder = {
|
|
31
|
+
select: 0,
|
|
32
|
+
edit: 1,
|
|
33
|
+
delete: 2
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Returns the default properties for a column
|
|
38
|
+
* @param {string} key - the key to use for the column
|
|
39
|
+
* @returns {Object} the default properties for a column
|
|
40
|
+
*/
|
|
41
|
+
// export const defaultProps = (key) => ({
|
|
42
|
+
// sortable: true,
|
|
43
|
+
// filterable: true,
|
|
44
|
+
// sorted: 'none',
|
|
45
|
+
// fields: { text: key }
|
|
46
|
+
// })
|
|
47
|
+
|
|
48
|
+
export const filterOperations = {
|
|
49
|
+
'=': (value, pattern) => value === pattern,
|
|
50
|
+
'<': (value, pattern) => value < pattern,
|
|
51
|
+
'>': (value, pattern) => value > pattern,
|
|
52
|
+
'<=': (value, pattern) => value <= pattern,
|
|
53
|
+
'>=': (value, pattern) => value >= pattern,
|
|
54
|
+
'~*': (value, pattern) => pattern.test(value),
|
|
55
|
+
'~': (value, pattern) => pattern.test(value),
|
|
56
|
+
'!=': (value, pattern) => value !== pattern,
|
|
57
|
+
'!~*': (value, pattern) => !pattern.test(value),
|
|
58
|
+
'!~': (value, pattern) => !pattern.test(value)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export const typeConverters = {
|
|
62
|
+
string: (value) => String(value),
|
|
63
|
+
number: (value) => Number(value),
|
|
64
|
+
boolean: (value) => value === 'true' || value === true,
|
|
65
|
+
date: (value) => new Date(value),
|
|
66
|
+
mixed: identity
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* A filter function that includes all rows.
|
|
71
|
+
*/
|
|
72
|
+
export const includeAll = () => true
|
package/src/convert.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { inferDataType } from './infer'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Converts an array of objects into a columnar structure, returning an object with two attributes:
|
|
5
|
+
*
|
|
6
|
+
* - columns, which contains an array of column names
|
|
7
|
+
* - data, which is an object with column names as keys and arrays as values.
|
|
8
|
+
*
|
|
9
|
+
* @param {Array<Object>} input
|
|
10
|
+
* @returns {import('./types').Dataframe}
|
|
11
|
+
*/
|
|
12
|
+
export function fromArray(input) {
|
|
13
|
+
const data = {}
|
|
14
|
+
let columns = []
|
|
15
|
+
|
|
16
|
+
input.forEach((items, index) => {
|
|
17
|
+
const keys = Object.keys(items)
|
|
18
|
+
const missing = columns.filter((x) => !keys.includes(x))
|
|
19
|
+
|
|
20
|
+
columns = [...columns, ...keys.filter((x) => !columns.includes(x))]
|
|
21
|
+
|
|
22
|
+
missing.forEach((key) => {
|
|
23
|
+
data[key] = [...data[key], null]
|
|
24
|
+
})
|
|
25
|
+
keys.forEach((key) => {
|
|
26
|
+
if (key in data) {
|
|
27
|
+
data[key] = [...data[key], items[key]]
|
|
28
|
+
} else {
|
|
29
|
+
data[key] = [...Array(index).fill(null), items[key]]
|
|
30
|
+
}
|
|
31
|
+
})
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
const types = columns.reduce((acc, x) => ({ ...acc, [x]: inferDataType(data[x]) }), {})
|
|
35
|
+
return { data, columns, types }
|
|
36
|
+
}
|