layerchart 0.0.1 → 0.0.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/README.md +2 -37
- package/components/Arc.svelte +77 -0
- package/components/Arc.svelte.d.ts +34 -0
- package/components/Area.svelte +47 -0
- package/components/Area.svelte.d.ts +31 -0
- package/components/AreaStack.svelte +40 -0
- package/components/AreaStack.svelte.d.ts +20 -0
- package/components/AxisX.svelte +52 -0
- package/components/AxisX.svelte.d.ts +23 -0
- package/components/AxisY.svelte +66 -0
- package/components/AxisY.svelte.d.ts +23 -0
- package/components/Bars.svelte +102 -0
- package/components/Bars.svelte.d.ts +35 -0
- package/components/Baseline.svelte +21 -0
- package/components/Baseline.svelte.d.ts +17 -0
- package/components/Chart.svelte +50 -0
- package/components/Chart.svelte.d.ts +24 -0
- package/components/Circle.svelte +15 -0
- package/components/Circle.svelte.d.ts +22 -0
- package/components/ConnectedPoints.svelte +68 -0
- package/components/ConnectedPoints.svelte.d.ts +18 -0
- package/components/Group.svelte +26 -0
- package/components/Group.svelte.d.ts +21 -0
- package/components/HighlightLine.svelte +52 -0
- package/components/HighlightLine.svelte.d.ts +17 -0
- package/components/HighlightRect.svelte +27 -0
- package/components/HighlightRect.svelte.d.ts +18 -0
- package/components/Labels.svelte +96 -0
- package/components/Labels.svelte.d.ts +22 -0
- package/components/Line.svelte +18 -0
- package/components/Line.svelte.d.ts +23 -0
- package/components/LinearGradient.svelte +27 -0
- package/components/LinearGradient.svelte.d.ts +27 -0
- package/components/Path.svelte +40 -0
- package/components/Path.svelte.d.ts +27 -0
- package/components/Points.svelte +58 -0
- package/components/Points.svelte.d.ts +19 -0
- package/components/Rect.svelte +25 -0
- package/components/Rect.svelte.d.ts +25 -0
- package/components/Text.svelte +129 -0
- package/components/Text.svelte.d.ts +28 -0
- package/components/Threshold.svelte +86 -0
- package/components/Threshold.svelte.d.ts +35 -0
- package/components/Tooltip.svelte +120 -0
- package/components/Tooltip.svelte.d.ts +33 -0
- package/components/index.d.ts +19 -0
- package/components/index.js +19 -0
- package/docs/Blockquote.svelte +7 -0
- package/docs/Blockquote.svelte.d.ts +23 -0
- package/docs/Code.svelte +6 -0
- package/docs/Code.svelte.d.ts +23 -0
- package/docs/Layout.svelte +20 -0
- package/docs/Layout.svelte.d.ts +29 -0
- package/docs/Link.svelte +7 -0
- package/docs/Link.svelte.d.ts +27 -0
- package/docs/Preview.svelte +23 -0
- package/docs/Preview.svelte.d.ts +21 -0
- package/index.d.ts +3 -0
- package/index.js +3 -0
- package/package.json +84 -26
- package/stores/motionStore.d.ts +8 -0
- package/stores/motionStore.js +16 -0
- package/utils/event.d.ts +4 -0
- package/utils/event.js +42 -0
- package/utils/genData.d.ts +32 -0
- package/utils/genData.js +59 -0
- package/utils/index.d.ts +1 -0
- package/utils/index.js +1 -0
- package/utils/math.d.ts +4 -0
- package/utils/math.js +6 -0
- package/utils/path.d.ts +5 -0
- package/utils/path.js +14 -0
- package/utils/pivot.d.ts +14 -0
- package/utils/pivot.js +36 -0
- package/utils/scales.d.ts +10 -0
- package/utils/scales.js +21 -0
- package/utils/stack.d.ts +14 -0
- package/utils/stack.js +69 -0
- package/utils/string.d.ts +4 -0
- package/utils/string.js +27 -0
- package/utils/ticks.d.ts +3 -0
- package/utils/ticks.js +157 -0
- package/.prettierrc +0 -6
- package/src/app.html +0 -12
- package/src/global.d.ts +0 -1
- package/src/routes/index.svelte +0 -2
- package/static/favicon.png +0 -0
- package/svelte.config.js +0 -15
- package/tsconfig.json +0 -31
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/** @typedef {typeof __propDef.props} LinkProps */
|
|
2
|
+
/** @typedef {typeof __propDef.events} LinkEvents */
|
|
3
|
+
/** @typedef {typeof __propDef.slots} LinkSlots */
|
|
4
|
+
export default class Link extends SvelteComponentTyped<{
|
|
5
|
+
[x: string]: any;
|
|
6
|
+
}, {
|
|
7
|
+
[evt: string]: CustomEvent<any>;
|
|
8
|
+
}, {
|
|
9
|
+
default: {};
|
|
10
|
+
}> {
|
|
11
|
+
}
|
|
12
|
+
export type LinkProps = typeof __propDef.props;
|
|
13
|
+
export type LinkEvents = typeof __propDef.events;
|
|
14
|
+
export type LinkSlots = typeof __propDef.slots;
|
|
15
|
+
import { SvelteComponentTyped } from "svelte";
|
|
16
|
+
declare const __propDef: {
|
|
17
|
+
props: {
|
|
18
|
+
[x: string]: any;
|
|
19
|
+
};
|
|
20
|
+
events: {
|
|
21
|
+
[evt: string]: CustomEvent<any>;
|
|
22
|
+
};
|
|
23
|
+
slots: {
|
|
24
|
+
default: {};
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<script >import Prism from 'prismjs';
|
|
2
|
+
import 'prism-svelte';
|
|
3
|
+
export let code = null;
|
|
4
|
+
export let language = 'svelte';
|
|
5
|
+
export let highlight = false;
|
|
6
|
+
$: displayCode = highlight ? Prism.highlight(code, Prism.languages.svelte, 'svelte') : code;
|
|
7
|
+
</script>
|
|
8
|
+
|
|
9
|
+
<div class="border border-black/20 rounded bg-white">
|
|
10
|
+
<div class="p-4">
|
|
11
|
+
<slot />
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
{#if displayCode}
|
|
15
|
+
<pre
|
|
16
|
+
class="language-{language} rounded"
|
|
17
|
+
style="margin: 0">
|
|
18
|
+
<code class="language-{language}">
|
|
19
|
+
{@html displayCode}
|
|
20
|
+
</code>
|
|
21
|
+
</pre>
|
|
22
|
+
{/if}
|
|
23
|
+
</div>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { SvelteComponentTyped } from "svelte";
|
|
2
|
+
import 'prism-svelte';
|
|
3
|
+
declare const __propDef: {
|
|
4
|
+
props: {
|
|
5
|
+
code?: any;
|
|
6
|
+
language?: string;
|
|
7
|
+
highlight?: boolean;
|
|
8
|
+
};
|
|
9
|
+
events: {
|
|
10
|
+
[evt: string]: CustomEvent<any>;
|
|
11
|
+
};
|
|
12
|
+
slots: {
|
|
13
|
+
default: {};
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
export declare type PreviewProps = typeof __propDef.props;
|
|
17
|
+
export declare type PreviewEvents = typeof __propDef.events;
|
|
18
|
+
export declare type PreviewSlots = typeof __propDef.slots;
|
|
19
|
+
export default class Preview extends SvelteComponentTyped<PreviewProps, PreviewEvents, PreviewSlots> {
|
|
20
|
+
}
|
|
21
|
+
export {};
|
package/index.d.ts
ADDED
package/index.js
ADDED
package/package.json
CHANGED
|
@@ -1,27 +1,85 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
2
|
+
"name": "layerchart",
|
|
3
|
+
"author": "Sean Lynch <techniq35@gmail.com>",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"repository": "techniq/layerchart",
|
|
6
|
+
"version": "0.0.5",
|
|
7
|
+
"devDependencies": {
|
|
8
|
+
"@sveltejs/adapter-static": "^1.0.0-next.21",
|
|
9
|
+
"@sveltejs/kit": "^1.0.0-next.201",
|
|
10
|
+
"@types/d3-array": "^3.0.2",
|
|
11
|
+
"@types/d3-scale": "^4.0.2",
|
|
12
|
+
"@types/d3-shape": "^3.0.2",
|
|
13
|
+
"@types/lodash-es": "^4.17.5",
|
|
14
|
+
"autoprefixer": "^10.4.0",
|
|
15
|
+
"mdsvex": "^0.9.8",
|
|
16
|
+
"prettier": "^2.5.0",
|
|
17
|
+
"prettier-plugin-svelte": "^2.5.0",
|
|
18
|
+
"prism-themes": "^1.9.0",
|
|
19
|
+
"svelte": "^3.44.2",
|
|
20
|
+
"svelte-check": "^2.2.10",
|
|
21
|
+
"svelte-preprocess": "^4.9.4",
|
|
22
|
+
"svelte2tsx": "^0.4.10",
|
|
23
|
+
"tailwindcss": "^2.2.19",
|
|
24
|
+
"tailwindcss-elevation": "^1.0.1",
|
|
25
|
+
"tslib": "^2.3.1",
|
|
26
|
+
"typescript": "^4.5.2",
|
|
27
|
+
"unist-util-visit": "^4.1.0"
|
|
28
|
+
},
|
|
29
|
+
"type": "module",
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@mdi/js": "^6.5.95",
|
|
32
|
+
"d3-array": "^3.1.1",
|
|
33
|
+
"d3-interpolate-path": "^2.2.3",
|
|
34
|
+
"d3-scale": "^4.0.2",
|
|
35
|
+
"d3-shape": "^3.0.1",
|
|
36
|
+
"date-fns": "^2.26.0",
|
|
37
|
+
"layercake": "^5.0.1",
|
|
38
|
+
"lodash-es": "^4.17.21",
|
|
39
|
+
"svelte-ux": "^0.0.105"
|
|
40
|
+
},
|
|
41
|
+
"exports": {
|
|
42
|
+
"./package.json": "./package.json",
|
|
43
|
+
"./components/Arc.svelte": "./components/Arc.svelte",
|
|
44
|
+
"./components/Area.svelte": "./components/Area.svelte",
|
|
45
|
+
"./components/AreaStack.svelte": "./components/AreaStack.svelte",
|
|
46
|
+
"./components/AxisX.svelte": "./components/AxisX.svelte",
|
|
47
|
+
"./components/AxisY.svelte": "./components/AxisY.svelte",
|
|
48
|
+
"./components/Bars.svelte": "./components/Bars.svelte",
|
|
49
|
+
"./components/Baseline.svelte": "./components/Baseline.svelte",
|
|
50
|
+
"./components/Chart.svelte": "./components/Chart.svelte",
|
|
51
|
+
"./components/Circle.svelte": "./components/Circle.svelte",
|
|
52
|
+
"./components/ConnectedPoints.svelte": "./components/ConnectedPoints.svelte",
|
|
53
|
+
"./components/Group.svelte": "./components/Group.svelte",
|
|
54
|
+
"./components/HighlightLine.svelte": "./components/HighlightLine.svelte",
|
|
55
|
+
"./components/HighlightRect.svelte": "./components/HighlightRect.svelte",
|
|
56
|
+
"./components/Labels.svelte": "./components/Labels.svelte",
|
|
57
|
+
"./components/Line.svelte": "./components/Line.svelte",
|
|
58
|
+
"./components/LinearGradient.svelte": "./components/LinearGradient.svelte",
|
|
59
|
+
"./components/Path.svelte": "./components/Path.svelte",
|
|
60
|
+
"./components/Points.svelte": "./components/Points.svelte",
|
|
61
|
+
"./components/Rect.svelte": "./components/Rect.svelte",
|
|
62
|
+
"./components/Text.svelte": "./components/Text.svelte",
|
|
63
|
+
"./components/Threshold.svelte": "./components/Threshold.svelte",
|
|
64
|
+
"./components/Tooltip.svelte": "./components/Tooltip.svelte",
|
|
65
|
+
"./components": "./components/index.js",
|
|
66
|
+
"./docs/Blockquote.svelte": "./docs/Blockquote.svelte",
|
|
67
|
+
"./docs/Code.svelte": "./docs/Code.svelte",
|
|
68
|
+
"./docs/Layout.svelte": "./docs/Layout.svelte",
|
|
69
|
+
"./docs/Link.svelte": "./docs/Link.svelte",
|
|
70
|
+
"./docs/Preview.svelte": "./docs/Preview.svelte",
|
|
71
|
+
".": "./index.js",
|
|
72
|
+
"./stores/motionStore": "./stores/motionStore.js",
|
|
73
|
+
"./utils/event": "./utils/event.js",
|
|
74
|
+
"./utils/genData": "./utils/genData.js",
|
|
75
|
+
"./utils": "./utils/index.js",
|
|
76
|
+
"./utils/math": "./utils/math.js",
|
|
77
|
+
"./utils/path": "./utils/path.js",
|
|
78
|
+
"./utils/pivot": "./utils/pivot.js",
|
|
79
|
+
"./utils/scales": "./utils/scales.js",
|
|
80
|
+
"./utils/stack": "./utils/stack.js",
|
|
81
|
+
"./utils/string": "./utils/string.js",
|
|
82
|
+
"./utils/ticks": "./utils/ticks.js"
|
|
83
|
+
},
|
|
84
|
+
"svelte": "./index.js"
|
|
85
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { spring, tweened } from 'svelte/motion';
|
|
2
|
+
/**
|
|
3
|
+
* Convenient wrapper to get motion store based on properties, or fall back to basic writable() store
|
|
4
|
+
*/
|
|
5
|
+
export declare function getMotionStore(value: any, options: {
|
|
6
|
+
spring?: boolean | Parameters<typeof spring>[1];
|
|
7
|
+
tweened?: boolean | Parameters<typeof tweened>[1];
|
|
8
|
+
}): import("svelte/motion").Tweened<unknown> | import("svelte/motion").Spring<any> | import("svelte/store").Writable<any>;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { writable } from 'svelte/store';
|
|
2
|
+
import { spring, tweened } from 'svelte/motion';
|
|
3
|
+
/**
|
|
4
|
+
* Convenient wrapper to get motion store based on properties, or fall back to basic writable() store
|
|
5
|
+
*/
|
|
6
|
+
export function getMotionStore(value, options) {
|
|
7
|
+
if (options.spring) {
|
|
8
|
+
return spring(value, options.spring === true ? undefined : options.spring);
|
|
9
|
+
}
|
|
10
|
+
else if (options.tweened) {
|
|
11
|
+
return tweened(value, options.tweened === true ? undefined : options.tweened);
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
return writable(value);
|
|
15
|
+
}
|
|
16
|
+
}
|
package/utils/event.d.ts
ADDED
package/utils/event.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { isSVGElement, isSVGGraphicsElement, isSVGSVGElement, isTouchEvent } from 'svelte-ux/types/typeGuards';
|
|
2
|
+
// See: https://github.com/airbnb/visx/blob/master/packages/visx-event/src/localPointGeneric.ts
|
|
3
|
+
export function localPoint(node, event) {
|
|
4
|
+
if (!node || !event)
|
|
5
|
+
return null;
|
|
6
|
+
const coords = getPointFromEvent(event);
|
|
7
|
+
// find top-most SVG
|
|
8
|
+
const svg = isSVGElement(node) ? node.ownerSVGElement : node;
|
|
9
|
+
const screenCTM = isSVGGraphicsElement(svg) ? svg.getScreenCTM() : null;
|
|
10
|
+
if (isSVGSVGElement(svg) && screenCTM) {
|
|
11
|
+
let point = svg.createSVGPoint();
|
|
12
|
+
point.x = coords.x;
|
|
13
|
+
point.y = coords.y;
|
|
14
|
+
point = point.matrixTransform(screenCTM.inverse());
|
|
15
|
+
return {
|
|
16
|
+
x: point.x,
|
|
17
|
+
y: point.y
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
// fall back to bounding box
|
|
21
|
+
const rect = node.getBoundingClientRect();
|
|
22
|
+
return {
|
|
23
|
+
x: coords.x - rect.left - node.clientLeft,
|
|
24
|
+
y: coords.y - rect.top - node.clientTop
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
function getPointFromEvent(event) {
|
|
28
|
+
if (!event)
|
|
29
|
+
return { x: 0, y: 0 };
|
|
30
|
+
if (isTouchEvent(event)) {
|
|
31
|
+
return event.changedTouches.length > 0
|
|
32
|
+
? {
|
|
33
|
+
x: event.changedTouches[0].clientX,
|
|
34
|
+
y: event.changedTouches[0].clientY
|
|
35
|
+
}
|
|
36
|
+
: { x: 0, y: 0 };
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
x: event.clientX,
|
|
40
|
+
y: event.clientY
|
|
41
|
+
};
|
|
42
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Get random number between min (inclusive) and max (exclusive)
|
|
3
|
+
* see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random#getting_a_random_number_between_0_inclusive_and_1_exclusive
|
|
4
|
+
*/
|
|
5
|
+
export declare function getRandomNumber(min: number, max: number): number;
|
|
6
|
+
/**
|
|
7
|
+
* Get random integer between min (inclusive) and max (inclusive by default)
|
|
8
|
+
* see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random#getting_a_random_integer_between_two_values_inclusive
|
|
9
|
+
*/
|
|
10
|
+
export declare function getRandomInteger(min: number, max: number, includeMax?: boolean): number;
|
|
11
|
+
export declare function createDateSeries(options: {
|
|
12
|
+
count?: number;
|
|
13
|
+
min: number;
|
|
14
|
+
max: number;
|
|
15
|
+
keys: Array<string>;
|
|
16
|
+
value: 'number' | 'integer';
|
|
17
|
+
}): {
|
|
18
|
+
date: Date;
|
|
19
|
+
}[];
|
|
20
|
+
export declare const wideData: {
|
|
21
|
+
year: string;
|
|
22
|
+
apples: number;
|
|
23
|
+
bananas: number;
|
|
24
|
+
cherries: number;
|
|
25
|
+
dates: number;
|
|
26
|
+
}[];
|
|
27
|
+
export declare const longData: {
|
|
28
|
+
year: string;
|
|
29
|
+
basket: number;
|
|
30
|
+
fruit: string;
|
|
31
|
+
value: number;
|
|
32
|
+
}[];
|
package/utils/genData.js
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { subDays } from 'date-fns';
|
|
2
|
+
/**
|
|
3
|
+
* Get random number between min (inclusive) and max (exclusive)
|
|
4
|
+
* see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random#getting_a_random_number_between_0_inclusive_and_1_exclusive
|
|
5
|
+
*/
|
|
6
|
+
export function getRandomNumber(min, max) {
|
|
7
|
+
return Math.random() * (max - min) + min;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Get random integer between min (inclusive) and max (inclusive by default)
|
|
11
|
+
* see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random#getting_a_random_integer_between_two_values_inclusive
|
|
12
|
+
*/
|
|
13
|
+
export function getRandomInteger(min, max, includeMax = true) {
|
|
14
|
+
min = Math.ceil(min);
|
|
15
|
+
max = Math.floor(max);
|
|
16
|
+
return Math.floor(Math.random() * (max - min + (includeMax ? 1 : 0)) + min);
|
|
17
|
+
}
|
|
18
|
+
export function createDateSeries(options) {
|
|
19
|
+
const now = new Date();
|
|
20
|
+
const count = options.count ?? 10;
|
|
21
|
+
const min = options.min;
|
|
22
|
+
const max = options.max;
|
|
23
|
+
const keys = options.keys ?? ['value'];
|
|
24
|
+
return Array.from({ length: count }).map((_, i) => {
|
|
25
|
+
return {
|
|
26
|
+
date: subDays(now, count - i - 1),
|
|
27
|
+
...Object.fromEntries(keys.map((key) => {
|
|
28
|
+
return [
|
|
29
|
+
key,
|
|
30
|
+
options.value === 'integer' ? getRandomInteger(min, max) : getRandomNumber(min, max)
|
|
31
|
+
];
|
|
32
|
+
}))
|
|
33
|
+
};
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
export const wideData = [
|
|
37
|
+
{ year: '2019', apples: 3840, bananas: 1920, cherries: 960, dates: 400 },
|
|
38
|
+
{ year: '2018', apples: 1600, bananas: 1440, cherries: 960, dates: 400 },
|
|
39
|
+
{ year: '2017', apples: 820, bananas: 1000, cherries: 640, dates: 400 },
|
|
40
|
+
{ year: '2016', apples: 820, bananas: 560, cherries: 720, dates: 400 }
|
|
41
|
+
];
|
|
42
|
+
export const longData = [
|
|
43
|
+
{ year: '2019', basket: 1, fruit: 'apples', value: 3840 },
|
|
44
|
+
{ year: '2019', basket: 1, fruit: 'bananas', value: 1920 },
|
|
45
|
+
{ year: '2019', basket: 2, fruit: 'cherries', value: 960 },
|
|
46
|
+
{ year: '2019', basket: 2, fruit: 'dates', value: 400 },
|
|
47
|
+
{ year: '2018', basket: 1, fruit: 'apples', value: 1600 },
|
|
48
|
+
{ year: '2018', basket: 1, fruit: 'bananas', value: 1440 },
|
|
49
|
+
{ year: '2018', basket: 2, fruit: 'cherries', value: 960 },
|
|
50
|
+
{ year: '2018', basket: 2, fruit: 'dates', value: 400 },
|
|
51
|
+
{ year: '2017', basket: 1, fruit: 'apples', value: 820 },
|
|
52
|
+
{ year: '2017', basket: 1, fruit: 'bananas', value: 1000 },
|
|
53
|
+
{ year: '2017', basket: 2, fruit: 'cherries', value: 640 },
|
|
54
|
+
{ year: '2017', basket: 2, fruit: 'dates', value: 400 },
|
|
55
|
+
{ year: '2016', basket: 1, fruit: 'apples', value: 820 },
|
|
56
|
+
{ year: '2016', basket: 1, fruit: 'bananas', value: 560 },
|
|
57
|
+
{ year: '2016', basket: 2, fruit: 'cherries', value: 720 },
|
|
58
|
+
{ year: '2016', basket: 2, fruit: 'dates', value: 400 }
|
|
59
|
+
];
|
package/utils/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { getMajorTicks, getMinorTicks } from './ticks';
|
package/utils/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { getMajorTicks, getMinorTicks } from './ticks';
|
package/utils/math.d.ts
ADDED
package/utils/math.js
ADDED
package/utils/path.d.ts
ADDED
package/utils/path.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Convert easing into path data with number of points
|
|
3
|
+
* see: https://svelte.dev/examples#easing
|
|
4
|
+
*/
|
|
5
|
+
export function getEasingPath(easing, count = 1000) {
|
|
6
|
+
let pathData = `M0 ${count}`;
|
|
7
|
+
for (let i = 1; i <= count; i++) {
|
|
8
|
+
pathData += `
|
|
9
|
+
L${(i / count) * count}
|
|
10
|
+
${count - easing(i / count) * count}
|
|
11
|
+
`;
|
|
12
|
+
}
|
|
13
|
+
return pathData;
|
|
14
|
+
}
|
package/utils/pivot.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare function getAccessor(key: any): any;
|
|
2
|
+
/**
|
|
3
|
+
* Pivot longer (columns to rows)
|
|
4
|
+
* - see: https://observablehq.com/d/3ea8d446f5ba96fe
|
|
5
|
+
* - see also: https://observablehq.com/d/ac2a320cf2b0adc4 as generator
|
|
6
|
+
*/
|
|
7
|
+
export declare function pivotLonger(data: any, columns: any, name: any, value: any): any;
|
|
8
|
+
/**
|
|
9
|
+
* Pivot wider (rows to columns)
|
|
10
|
+
* - see: https://github.com/d3/d3-array/issues/142#issuecomment-761861983
|
|
11
|
+
*/
|
|
12
|
+
export declare function pivotWider(data: any, column: any, name: any, value: any): any[];
|
|
13
|
+
export declare function first(items: any): any;
|
|
14
|
+
export declare function last(items: any): any;
|
package/utils/pivot.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { group } from 'd3-array';
|
|
2
|
+
export function getAccessor(key) {
|
|
3
|
+
if (typeof key === 'function') {
|
|
4
|
+
return key;
|
|
5
|
+
}
|
|
6
|
+
else {
|
|
7
|
+
return (d) => d[key];
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Pivot longer (columns to rows)
|
|
12
|
+
* - see: https://observablehq.com/d/3ea8d446f5ba96fe
|
|
13
|
+
* - see also: https://observablehq.com/d/ac2a320cf2b0adc4 as generator
|
|
14
|
+
*/
|
|
15
|
+
export function pivotLonger(data, columns, name, value) {
|
|
16
|
+
const keep = Object.keys(data[0]).filter((c) => !columns.includes(c));
|
|
17
|
+
return data.flatMap((d) => {
|
|
18
|
+
const base = keep.map((k) => [k, d[k]]);
|
|
19
|
+
return columns.map((column) => {
|
|
20
|
+
return Object.fromEntries([...base, [name, column], [value, d[column]]]);
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Pivot wider (rows to columns)
|
|
26
|
+
* - see: https://github.com/d3/d3-array/issues/142#issuecomment-761861983
|
|
27
|
+
*/
|
|
28
|
+
export function pivotWider(data, column, name, value) {
|
|
29
|
+
return Array.from(group(data, (d) => d[column]), ([columnVal, items]) => Object.fromEntries([[column, columnVal]].concat(items.map((d) => [d[name], d[value]]))));
|
|
30
|
+
}
|
|
31
|
+
export function first(items) {
|
|
32
|
+
return items[0];
|
|
33
|
+
}
|
|
34
|
+
export function last(items) {
|
|
35
|
+
return items[items.length - 1];
|
|
36
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Implemenation for missing `scaleBand().invert()`
|
|
3
|
+
*
|
|
4
|
+
* See: https://stackoverflow.com/a/50846323/191902
|
|
5
|
+
* https://github.com/d3/d3-scale/pull/64
|
|
6
|
+
* https://github.com/vega/vega-scale/blob/master/src/scaleBand.js#L118
|
|
7
|
+
* https://observablehq.com/@d3/ordinal-brushing
|
|
8
|
+
*/
|
|
9
|
+
export declare function scaleBandInvert(scale: any): (value: any) => any;
|
|
10
|
+
export declare function isScaleBand(scale: any): boolean;
|
package/utils/scales.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Implemenation for missing `scaleBand().invert()`
|
|
3
|
+
*
|
|
4
|
+
* See: https://stackoverflow.com/a/50846323/191902
|
|
5
|
+
* https://github.com/d3/d3-scale/pull/64
|
|
6
|
+
* https://github.com/vega/vega-scale/blob/master/src/scaleBand.js#L118
|
|
7
|
+
* https://observablehq.com/@d3/ordinal-brushing
|
|
8
|
+
*/
|
|
9
|
+
export function scaleBandInvert(scale) {
|
|
10
|
+
const domain = scale.domain();
|
|
11
|
+
const paddingOuter = scale(domain[0]);
|
|
12
|
+
const eachBand = scale.step();
|
|
13
|
+
return function (value) {
|
|
14
|
+
// TODO: Should this use Math.round to better select? https://stackoverflow.com/questions/38633082/d3-getting-invert-value-of-band-scales/50846323#comment104743795_50846323
|
|
15
|
+
const index = Math.floor((value - paddingOuter) / eachBand);
|
|
16
|
+
return domain[Math.max(0, Math.min(index, domain.length - 1))];
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
export function isScaleBand(scale) {
|
|
20
|
+
return typeof scale.bandwidth === 'function';
|
|
21
|
+
}
|
package/utils/stack.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { stackOffsetNone } from 'd3-shape';
|
|
2
|
+
declare type OffsetType = typeof stackOffsetNone;
|
|
3
|
+
export declare function createStackData(data: any[], options: {
|
|
4
|
+
xKey: string;
|
|
5
|
+
groupBy?: string;
|
|
6
|
+
stackBy?: string;
|
|
7
|
+
offset?: OffsetType;
|
|
8
|
+
}): any[];
|
|
9
|
+
/**
|
|
10
|
+
* Function to offset each layer by the maximum of the previous layer
|
|
11
|
+
* - see: https://observablehq.com/@mkfreeman/separated-bar-chart
|
|
12
|
+
*/
|
|
13
|
+
export declare function stackOffsetSeparated(series: any, order: any): void;
|
|
14
|
+
export {};
|
package/utils/stack.js
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { flatGroup, max, sum } from 'd3-array';
|
|
2
|
+
import { stack } from 'd3-shape';
|
|
3
|
+
import { pivotWider } from './pivot';
|
|
4
|
+
export function createStackData(data, options) {
|
|
5
|
+
if (options.groupBy) {
|
|
6
|
+
// Group then Stack (if needed)
|
|
7
|
+
const groupedData = flatGroup(data, (d) => d[options.xKey], (d) => d[options.groupBy]);
|
|
8
|
+
const result = groupedData.flatMap((d, i) => {
|
|
9
|
+
const groupKeys = d.slice(0, -1); // all but last item
|
|
10
|
+
const itemData = d.slice(-1)[0]; // last item
|
|
11
|
+
const pivotData = pivotWider(itemData, options.xKey, options.stackBy, 'value');
|
|
12
|
+
const stackKeys = [...new Set(itemData.map((d) => d[options.stackBy]))];
|
|
13
|
+
const stackData = stack().keys(stackKeys).offset(options.offset)(pivotData);
|
|
14
|
+
//console.log({ pivotData, stackData })
|
|
15
|
+
return stackData.flatMap((series) => {
|
|
16
|
+
//console.log({ series })
|
|
17
|
+
return series.flatMap((s) => {
|
|
18
|
+
return {
|
|
19
|
+
...itemData[0],
|
|
20
|
+
keys: options.stackBy ? [...groupKeys, series.key] : groupKeys,
|
|
21
|
+
values: options.stackBy ? [s[0], s[1]] : [0, sum(itemData, (d) => d.value)]
|
|
22
|
+
};
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
return result;
|
|
27
|
+
}
|
|
28
|
+
else if (options.stackBy) {
|
|
29
|
+
// Stack only
|
|
30
|
+
const pivotData = pivotWider(data, options.xKey, options.stackBy, 'value');
|
|
31
|
+
const stackKeys = [...new Set(data.map((d) => d[options.stackBy]))];
|
|
32
|
+
const stackData = stack().keys(stackKeys).offset(options.offset)(pivotData);
|
|
33
|
+
const result = stackData.flatMap((series) => {
|
|
34
|
+
return series.flatMap((s) => {
|
|
35
|
+
return {
|
|
36
|
+
...s.data,
|
|
37
|
+
keys: [s.data[options.xKey], series.key],
|
|
38
|
+
values: [s[0], s[1]]
|
|
39
|
+
};
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
return result;
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
// TODO: Do anything if no group or stack? Convert to { ...d, keys: [...}, values: [...] ]}?
|
|
46
|
+
return data;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Function to offset each layer by the maximum of the previous layer
|
|
51
|
+
* - see: https://observablehq.com/@mkfreeman/separated-bar-chart
|
|
52
|
+
*/
|
|
53
|
+
// TODO: Try to find way to support separated with createStackData() (which has isolated stacked per group)
|
|
54
|
+
export function stackOffsetSeparated(series, order) {
|
|
55
|
+
const gap = 200; // TODO: Determine way to pass in as option (curry?)
|
|
56
|
+
if (!((n = series.length) > 1))
|
|
57
|
+
return;
|
|
58
|
+
// Standard series
|
|
59
|
+
for (var i = 1, s0, s1 = series[order[0]], n, m = s1.length; i < n; ++i) {
|
|
60
|
+
(s0 = s1), (s1 = series[order[i]]);
|
|
61
|
+
let base = max(s0, (d) => d[1]) + gap; // here is where you calculate the maximum of the previous layer
|
|
62
|
+
for (var j = 0; j < m; ++j) {
|
|
63
|
+
// Set the height based on the data values, shifted up by the previous layer
|
|
64
|
+
let diff = s1[j][1] - s1[j][0];
|
|
65
|
+
s1[j][0] = base;
|
|
66
|
+
s1[j][1] = base + diff;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
package/utils/string.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { memoize } from 'lodash-es';
|
|
2
|
+
const MEASUREMENT_ELEMENT_ID = '__text_measurement_id';
|
|
3
|
+
function _getStringWidth(str, style) {
|
|
4
|
+
try {
|
|
5
|
+
// Calculate length of each word to be used to determine number of words per line
|
|
6
|
+
let textEl = document.getElementById(MEASUREMENT_ELEMENT_ID);
|
|
7
|
+
if (!textEl) {
|
|
8
|
+
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
|
9
|
+
svg.style.width = '0';
|
|
10
|
+
svg.style.height = '0';
|
|
11
|
+
svg.style.position = 'absolute';
|
|
12
|
+
svg.style.top = '-100%';
|
|
13
|
+
svg.style.left = '-100%';
|
|
14
|
+
textEl = document.createElementNS('http://www.w3.org/2000/svg', 'text');
|
|
15
|
+
textEl.setAttribute('id', MEASUREMENT_ELEMENT_ID);
|
|
16
|
+
svg.appendChild(textEl);
|
|
17
|
+
document.body.appendChild(svg);
|
|
18
|
+
}
|
|
19
|
+
Object.assign(textEl.style, style);
|
|
20
|
+
textEl.textContent = str;
|
|
21
|
+
return textEl.getComputedTextLength();
|
|
22
|
+
}
|
|
23
|
+
catch (e) {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
export const getStringWidth = memoize(_getStringWidth, (str, style) => `${str}_${JSON.stringify(style)}`);
|
package/utils/ticks.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export declare function getMajorTicks(start: Date, end: Date): import("d3-time").TimeInterval;
|
|
2
|
+
export declare function formatMajorTick(date: Date, rangeStart: Date, rangeEnd: Date): string;
|
|
3
|
+
export declare function getMinorTicks(start: Date, end: Date): import("d3-time").TimeInterval;
|