svelte-plotly.js 0.3.1 → 0.4.0
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/lib/Plot.svelte +150 -0
- package/dist/lib/Plot.svelte.d.ts +74 -0
- package/package.json +31 -35
- package/.eslintrc.cjs +0 -20
- package/.prettierrc +0 -7
- package/.vscode/settings.json +0 -3
- package/src/app.d.ts +0 -10
- package/src/app.html +0 -12
- package/src/lib/Plot.svelte +0 -281
- package/src/routes/index.svelte +0 -103
- package/src/types/plotly.d.ts +0 -3
- package/static/favicon.png +0 -0
- package/svelte.config.js +0 -15
- package/tsconfig.json +0 -17
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
<script context="module"></script>
|
|
2
|
+
|
|
3
|
+
<script>import { onMount, onDestroy, createEventDispatcher } from "svelte";
|
|
4
|
+
import { debounce as debouncify } from "lodash-es";
|
|
5
|
+
const browser = typeof window === "object";
|
|
6
|
+
const nextFrame = browser ? requestAnimationFrame : () => void 0;
|
|
7
|
+
async function loadPlotly() {
|
|
8
|
+
if (!browser) return;
|
|
9
|
+
if (libPlotly === void 0) {
|
|
10
|
+
if (window.Plotly) {
|
|
11
|
+
libPlotly = window.Plotly;
|
|
12
|
+
} else {
|
|
13
|
+
const p = await import("plotly.js-dist");
|
|
14
|
+
if (libPlotly === void 0) libPlotly = "default" in p ? p.default : p;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
const DEFAULT_WIDTH = 500;
|
|
19
|
+
const DEFAULT_HEIGHT = 300;
|
|
20
|
+
const events = {
|
|
21
|
+
plotly_afterexport: "afterExport",
|
|
22
|
+
plotly_afterplot: "afterPlot",
|
|
23
|
+
plotly_animated: "animated",
|
|
24
|
+
plotly_animating: "animating",
|
|
25
|
+
plotly_animatingframe: "animatingFrame",
|
|
26
|
+
plotly_animationinterrupted: "animationInterrupted",
|
|
27
|
+
plotly_autosize: "autoSize",
|
|
28
|
+
plotly_beforeexport: "beforeExport",
|
|
29
|
+
plotly_beforehover: "beforeHover",
|
|
30
|
+
plotly_beforeplot: "beforePlot",
|
|
31
|
+
plotly_buttonclicked: "buttonClicked",
|
|
32
|
+
plotly_click: "click",
|
|
33
|
+
plotly_clickannotation: "clickAnnotation",
|
|
34
|
+
plotly_deselect: "deselect",
|
|
35
|
+
plotly_doubleclick: "doubleClick",
|
|
36
|
+
plotly_framework: "framework",
|
|
37
|
+
plotly_hover: "hover",
|
|
38
|
+
plotly_legendclick: "legendClick",
|
|
39
|
+
plotly_legenddoubleclick: "legendDoubleClick",
|
|
40
|
+
plotly_react: "react",
|
|
41
|
+
plotly_redraw: "redraw",
|
|
42
|
+
plotly_relayout: "relayout",
|
|
43
|
+
plotly_relayouting: "relayouting",
|
|
44
|
+
plotly_restyle: "restyle",
|
|
45
|
+
plotly_selected: "selected",
|
|
46
|
+
plotly_selecting: "selecting",
|
|
47
|
+
plotly_sliderchange: "sliderChange",
|
|
48
|
+
plotly_sliderend: "sliderEnd",
|
|
49
|
+
plotly_sliderstart: "sliderStart",
|
|
50
|
+
plotly_sunburstclick: "sunburstClick",
|
|
51
|
+
plotly_transitioned: "transitioned",
|
|
52
|
+
plotly_transitioning: "transitioning",
|
|
53
|
+
plotly_transitioninterrupted: "transitionInterrupted",
|
|
54
|
+
plotly_unhover: "unhover",
|
|
55
|
+
plotly_update: "update",
|
|
56
|
+
plotly_webglcontextlost: "webGLContextLost"
|
|
57
|
+
// TODO add all plotly_${traceType}click
|
|
58
|
+
};
|
|
59
|
+
const dispatch = createEventDispatcher();
|
|
60
|
+
export let element = void 0;
|
|
61
|
+
export let plot = void 0;
|
|
62
|
+
export let libPlotly = void 0;
|
|
63
|
+
export let data;
|
|
64
|
+
export let layout = void 0;
|
|
65
|
+
export let config = void 0;
|
|
66
|
+
export let fillParent = false;
|
|
67
|
+
export let debounce = 0;
|
|
68
|
+
let className = "";
|
|
69
|
+
export { className as class };
|
|
70
|
+
onMount(async () => {
|
|
71
|
+
window.global = window;
|
|
72
|
+
await loadPlotly();
|
|
73
|
+
});
|
|
74
|
+
let datarevision = 0;
|
|
75
|
+
let previousLib = libPlotly;
|
|
76
|
+
let previousPlot = plot;
|
|
77
|
+
let width = DEFAULT_WIDTH;
|
|
78
|
+
let height = DEFAULT_HEIGHT;
|
|
79
|
+
$: debounceWait = typeof debounce === "object" ? debounce.wait : debounce ?? 0;
|
|
80
|
+
$: debounceOptions = typeof debounce === "object" ? debounce : {};
|
|
81
|
+
$: data, datarevision = (datarevision + 1) % 1e3;
|
|
82
|
+
$: layout_ = { datarevision, width, height, ...layout };
|
|
83
|
+
$: config_ = { displaylogo: false, ...config };
|
|
84
|
+
$: draw(libPlotly, element, data, layout_, config_);
|
|
85
|
+
$: {
|
|
86
|
+
if (element && previousLib !== libPlotly) {
|
|
87
|
+
previousLib?.purge(element);
|
|
88
|
+
plot = void 0;
|
|
89
|
+
}
|
|
90
|
+
previousLib = libPlotly;
|
|
91
|
+
loadPlotly();
|
|
92
|
+
}
|
|
93
|
+
$: if (previousPlot !== plot) {
|
|
94
|
+
for (const [plotlyEvent, svelteEvent] of Object.entries(events)) {
|
|
95
|
+
previousPlot?.removeAllListeners?.(plotlyEvent);
|
|
96
|
+
plot?.on(plotlyEvent, (e) => dispatch(svelteEvent, e));
|
|
97
|
+
}
|
|
98
|
+
previousPlot = plot;
|
|
99
|
+
}
|
|
100
|
+
const drawUndebounced = (lib, e, d, l, c) => {
|
|
101
|
+
if (e) lib?.react(e, d, l, c).then((p) => plot = p);
|
|
102
|
+
};
|
|
103
|
+
$: draw = debouncify(drawUndebounced, debounceWait, debounceOptions);
|
|
104
|
+
onDestroy(() => element && libPlotly?.purge(element));
|
|
105
|
+
$: fillParent, nextFrame(onResize);
|
|
106
|
+
$: fillParentWidth = fillParent === true || fillParent === "width";
|
|
107
|
+
$: fillParentHeight = fillParent === true || fillParent === "height";
|
|
108
|
+
$: parent = element?.parentElement;
|
|
109
|
+
let lastParent = null;
|
|
110
|
+
$: {
|
|
111
|
+
parentMounted(parent);
|
|
112
|
+
parentUnmounted(lastParent);
|
|
113
|
+
lastParent = parent;
|
|
114
|
+
}
|
|
115
|
+
let resizeObserver;
|
|
116
|
+
onMount(() => resizeObserver = new ResizeObserver(onResize));
|
|
117
|
+
const parentMounted = (parent2) => parent2 && resizeObserver?.observe(parent2);
|
|
118
|
+
const parentUnmounted = (parent2) => parent2 && resizeObserver?.unobserve(parent2);
|
|
119
|
+
function onResize() {
|
|
120
|
+
if (!parent || !element) return;
|
|
121
|
+
const { offsetHeight, offsetWidth } = parent;
|
|
122
|
+
const { paddingLeft, paddingTop, paddingRight, paddingBottom } = window.getComputedStyle(parent);
|
|
123
|
+
const maxWidth = offsetWidth - parseInt(paddingLeft) - parseInt(paddingRight);
|
|
124
|
+
const maxHeight = offsetHeight - parseInt(paddingTop) - parseInt(paddingRight);
|
|
125
|
+
width = fillParentWidth ? maxWidth : DEFAULT_WIDTH;
|
|
126
|
+
height = fillParentHeight ? maxHeight : DEFAULT_HEIGHT;
|
|
127
|
+
}
|
|
128
|
+
</script>
|
|
129
|
+
|
|
130
|
+
<div
|
|
131
|
+
class={className}
|
|
132
|
+
class:fillParent
|
|
133
|
+
class:fillParentWidth
|
|
134
|
+
class:fillParentHeight
|
|
135
|
+
bind:this={element}
|
|
136
|
+
/>
|
|
137
|
+
|
|
138
|
+
<style>.fillParent {
|
|
139
|
+
overflow: visible;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
.fillParentWidth {
|
|
143
|
+
width: 0 !important;
|
|
144
|
+
max-width: 0 !important;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
.fillParentHeight {
|
|
148
|
+
height: 0 !important;
|
|
149
|
+
max-height: 0 !important;
|
|
150
|
+
}</style>
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { SvelteComponent } from "svelte";
|
|
2
|
+
import type { Data, Layout, Config, PlotlyHTMLElement, BeforePlotEvent, ClickAnnotationEvent, FrameAnimationEvent, LegendClickEvent, PlotMouseEvent, PlotHoverEvent, PlotRelayoutEvent, PlotRestyleEvent, PlotSelectionEvent, SliderEndEvent, SliderChangeEvent, SliderStartEvent, SunburstClickEvent } from 'plotly.js';
|
|
3
|
+
export type { Data, Layout, Config, PlotlyHTMLElement, BeforePlotEvent, ClickAnnotationEvent, FrameAnimationEvent, LegendClickEvent, PlotMouseEvent, PlotHoverEvent, PlotRelayoutEvent, PlotRestyleEvent, PlotSelectionEvent, SliderChangeEvent, SliderStartEvent, SunburstClickEvent };
|
|
4
|
+
export type FillParent = boolean | 'width' | 'height';
|
|
5
|
+
import type { DebounceSettings } from 'lodash-es';
|
|
6
|
+
export interface DebounceOptions extends DebounceSettings {
|
|
7
|
+
wait: number;
|
|
8
|
+
}
|
|
9
|
+
export interface ButtonClickedEvent {
|
|
10
|
+
menu: any;
|
|
11
|
+
button: any;
|
|
12
|
+
active: any;
|
|
13
|
+
}
|
|
14
|
+
export interface PlotUpdateEvent {
|
|
15
|
+
data: Data;
|
|
16
|
+
layout: Layout;
|
|
17
|
+
}
|
|
18
|
+
declare const __propDef: {
|
|
19
|
+
props: {
|
|
20
|
+
element?: HTMLDivElement | (null | undefined);
|
|
21
|
+
plot?: PlotlyHTMLElement | (null | undefined);
|
|
22
|
+
libPlotly?: typeof import("plotly.js-dist") | null | undefined;
|
|
23
|
+
data: Data[];
|
|
24
|
+
layout?: Partial<Layout> | undefined;
|
|
25
|
+
config?: Partial<Config> | undefined;
|
|
26
|
+
fillParent?: FillParent;
|
|
27
|
+
debounce?: number | DebounceOptions;
|
|
28
|
+
class?: string;
|
|
29
|
+
};
|
|
30
|
+
slots: {};
|
|
31
|
+
events: {
|
|
32
|
+
afterExport: undefined;
|
|
33
|
+
afterPlot: undefined;
|
|
34
|
+
animated: undefined;
|
|
35
|
+
animating: undefined;
|
|
36
|
+
animatingFrame: FrameAnimationEvent;
|
|
37
|
+
animationInterrupted: undefined;
|
|
38
|
+
autoSize: undefined;
|
|
39
|
+
beforeExport: undefined;
|
|
40
|
+
beforeHover: PlotMouseEvent;
|
|
41
|
+
beforePlot: BeforePlotEvent;
|
|
42
|
+
buttonClicked: ButtonClickedEvent;
|
|
43
|
+
click: PlotMouseEvent;
|
|
44
|
+
clickAnnotation: ClickAnnotationEvent;
|
|
45
|
+
deselect: undefined;
|
|
46
|
+
doubleClick: undefined;
|
|
47
|
+
framework: undefined;
|
|
48
|
+
hover: PlotHoverEvent;
|
|
49
|
+
legendClick: LegendClickEvent;
|
|
50
|
+
legendDoubleClick: LegendClickEvent;
|
|
51
|
+
react: PlotUpdateEvent;
|
|
52
|
+
redraw: undefined;
|
|
53
|
+
relayout: PlotRelayoutEvent;
|
|
54
|
+
relayouting: PlotRelayoutEvent;
|
|
55
|
+
restyle: PlotRestyleEvent;
|
|
56
|
+
selected: PlotSelectionEvent;
|
|
57
|
+
selecting: PlotSelectionEvent;
|
|
58
|
+
sliderChange: SliderChangeEvent;
|
|
59
|
+
sliderEnd: SliderEndEvent;
|
|
60
|
+
sliderStart: SliderStartEvent;
|
|
61
|
+
sunburstClick: SunburstClickEvent;
|
|
62
|
+
transitioned: undefined;
|
|
63
|
+
transitioning: undefined;
|
|
64
|
+
transitionInterrupted: undefined;
|
|
65
|
+
unhover: PlotMouseEvent;
|
|
66
|
+
update: PlotUpdateEvent;
|
|
67
|
+
webGLContextLost: undefined;
|
|
68
|
+
};
|
|
69
|
+
};
|
|
70
|
+
export type PlotProps = typeof __propDef.props;
|
|
71
|
+
export type PlotEvents = typeof __propDef.events;
|
|
72
|
+
export type PlotSlots = typeof __propDef.slots;
|
|
73
|
+
export default class Plot extends SvelteComponent<PlotProps, PlotEvents, PlotSlots> {
|
|
74
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svelte-plotly.js",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"author": {
|
|
5
5
|
"name": "Michal Grňo (m93a)",
|
|
6
6
|
"url": "https://github.com/m93a/"
|
|
@@ -10,45 +10,38 @@
|
|
|
10
10
|
"bugs": {
|
|
11
11
|
"url": "https://github.com/m93a/svelte-plotly.js/issues"
|
|
12
12
|
},
|
|
13
|
-
"packageManager": "yarn@1.22.5",
|
|
14
13
|
"license": "MIT",
|
|
15
|
-
"
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
"prepare": "svelte-kit sync",
|
|
26
|
-
"check": "svelte-check --tsconfig ./tsconfig.json",
|
|
27
|
-
"check:watch": "svelte-check --tsconfig ./tsconfig.json --watch",
|
|
28
|
-
"lint": "prettier --ignore-path .gitignore --check --plugin-search-dir=. . && eslint --ignore-path .gitignore .",
|
|
29
|
-
"format": "prettier --ignore-path .gitignore --write --plugin-search-dir=. ."
|
|
14
|
+
"type": "module",
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"types": "./dist/lib/Plot.svelte.d.ts",
|
|
19
|
+
"exports": {
|
|
20
|
+
".": {
|
|
21
|
+
"types": "./dist/lib/Plot.svelte.d.ts",
|
|
22
|
+
"svelte": "./dist/lib/Plot.svelte"
|
|
23
|
+
}
|
|
30
24
|
},
|
|
31
25
|
"devDependencies": {
|
|
32
|
-
"@sveltejs/
|
|
33
|
-
"@sveltejs/
|
|
34
|
-
"@typescript-eslint/eslint-plugin": "^
|
|
35
|
-
"@typescript-eslint/parser": "^
|
|
26
|
+
"@sveltejs/package": "^2.3.1",
|
|
27
|
+
"@sveltejs/vite-plugin-svelte": "^3.1.1",
|
|
28
|
+
"@typescript-eslint/eslint-plugin": "^7.14.1",
|
|
29
|
+
"@typescript-eslint/parser": "^7.14.1",
|
|
36
30
|
"eslint": "^8.12.0",
|
|
37
|
-
"eslint-config-prettier": "^
|
|
38
|
-
"eslint-plugin-
|
|
39
|
-
"prettier": "^2.5.1",
|
|
40
|
-
"prettier-plugin-svelte": "^2.5.0",
|
|
31
|
+
"eslint-config-prettier": "^9.1.0",
|
|
32
|
+
"eslint-plugin-svelte": "^2.39.0",
|
|
41
33
|
"plotly.js-dist": "^2.12.1",
|
|
34
|
+
"prettier": "^3.3.2",
|
|
35
|
+
"prettier-plugin-svelte": "^3.2.5",
|
|
42
36
|
"sass": "^1.51.0",
|
|
43
|
-
"svelte": "^3.
|
|
44
|
-
"svelte-
|
|
45
|
-
"svelte-preprocess": "^4.10.1",
|
|
46
|
-
"svelte2tsx": "^0.5.9",
|
|
37
|
+
"svelte-check": "^3.8.4",
|
|
38
|
+
"svelte-preprocess": "^6.0.1",
|
|
47
39
|
"tslib": "^2.3.1",
|
|
48
|
-
"typescript": "~
|
|
40
|
+
"typescript": "~5.5.2",
|
|
41
|
+
"vite": "^5.2.13"
|
|
49
42
|
},
|
|
50
|
-
"type": "module",
|
|
51
43
|
"dependencies": {
|
|
44
|
+
"svelte": "^4.2.18",
|
|
52
45
|
"@types/lodash-es": "^4.17.6",
|
|
53
46
|
"@types/plotly.js": "^2.12.5",
|
|
54
47
|
"lodash-es": "^4.17"
|
|
@@ -56,8 +49,11 @@
|
|
|
56
49
|
"peerDependencies": {
|
|
57
50
|
"plotly.js-dist": "^2.12"
|
|
58
51
|
},
|
|
59
|
-
"
|
|
60
|
-
|
|
61
|
-
"
|
|
52
|
+
"scripts": {
|
|
53
|
+
"dev": "vite dev",
|
|
54
|
+
"build": "svelte-package -i src/lib -o dist/lib",
|
|
55
|
+
"check": "svelte-check --tsconfig ./tsconfig.json",
|
|
56
|
+
"lint": "prettier --check src/ && eslint .",
|
|
57
|
+
"format": "prettier --write src/"
|
|
62
58
|
}
|
|
63
|
-
}
|
|
59
|
+
}
|
package/.eslintrc.cjs
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
module.exports = {
|
|
2
|
-
root: true,
|
|
3
|
-
parser: '@typescript-eslint/parser',
|
|
4
|
-
extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'prettier'],
|
|
5
|
-
plugins: ['svelte3', '@typescript-eslint'],
|
|
6
|
-
ignorePatterns: ['*.cjs'],
|
|
7
|
-
overrides: [{ files: ['*.svelte'], processor: 'svelte3/svelte3' }],
|
|
8
|
-
settings: {
|
|
9
|
-
'svelte3/typescript': () => require('typescript')
|
|
10
|
-
},
|
|
11
|
-
parserOptions: {
|
|
12
|
-
sourceType: 'module',
|
|
13
|
-
ecmaVersion: 2020
|
|
14
|
-
},
|
|
15
|
-
env: {
|
|
16
|
-
browser: true,
|
|
17
|
-
es2017: true,
|
|
18
|
-
node: true
|
|
19
|
-
}
|
|
20
|
-
};
|
package/.prettierrc
DELETED
package/.vscode/settings.json
DELETED
package/src/app.d.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/// <reference types="@sveltejs/kit" />
|
|
2
|
-
|
|
3
|
-
// See https://kit.svelte.dev/docs/types#app
|
|
4
|
-
// for information about these interfaces
|
|
5
|
-
declare namespace App {
|
|
6
|
-
// interface Locals {}
|
|
7
|
-
// interface Platform {}
|
|
8
|
-
// interface Session {}
|
|
9
|
-
// interface Stuff {}
|
|
10
|
-
}
|
package/src/app.html
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="utf-8" />
|
|
5
|
-
<link rel="icon" href="%svelte.assets%/favicon.png" />
|
|
6
|
-
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
7
|
-
%svelte.head%
|
|
8
|
-
</head>
|
|
9
|
-
<body>
|
|
10
|
-
<div>%svelte.body%</div>
|
|
11
|
-
</body>
|
|
12
|
-
</html>
|
package/src/lib/Plot.svelte
DELETED
|
@@ -1,281 +0,0 @@
|
|
|
1
|
-
<script context="module" lang="ts">
|
|
2
|
-
import type {
|
|
3
|
-
Data,
|
|
4
|
-
Layout,
|
|
5
|
-
Config,
|
|
6
|
-
PlotlyHTMLElement,
|
|
7
|
-
BeforePlotEvent,
|
|
8
|
-
ClickAnnotationEvent,
|
|
9
|
-
FrameAnimationEvent,
|
|
10
|
-
LegendClickEvent,
|
|
11
|
-
PlotMouseEvent,
|
|
12
|
-
PlotHoverEvent,
|
|
13
|
-
PlotRelayoutEvent,
|
|
14
|
-
PlotRestyleEvent,
|
|
15
|
-
PlotSelectionEvent,
|
|
16
|
-
SliderEndEvent,
|
|
17
|
-
SliderChangeEvent,
|
|
18
|
-
SliderStartEvent,
|
|
19
|
-
SunburstClickEvent
|
|
20
|
-
} from 'plotly.js';
|
|
21
|
-
|
|
22
|
-
export type {
|
|
23
|
-
Data,
|
|
24
|
-
Layout,
|
|
25
|
-
Config,
|
|
26
|
-
PlotlyHTMLElement,
|
|
27
|
-
BeforePlotEvent,
|
|
28
|
-
ClickAnnotationEvent,
|
|
29
|
-
FrameAnimationEvent,
|
|
30
|
-
LegendClickEvent,
|
|
31
|
-
PlotMouseEvent,
|
|
32
|
-
PlotHoverEvent,
|
|
33
|
-
PlotRelayoutEvent,
|
|
34
|
-
PlotRestyleEvent,
|
|
35
|
-
PlotSelectionEvent,
|
|
36
|
-
SliderChangeEvent,
|
|
37
|
-
SliderStartEvent,
|
|
38
|
-
SunburstClickEvent
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
export type FillParent = boolean | 'width' | 'height';
|
|
42
|
-
import type { DebounceSettings } from 'lodash-es';
|
|
43
|
-
|
|
44
|
-
export interface DebounceOptions extends DebounceSettings {
|
|
45
|
-
wait: number;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export interface ButtonClickedEvent {
|
|
49
|
-
menu: any;
|
|
50
|
-
button: any;
|
|
51
|
-
active: any;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export interface PlotUpdateEvent {
|
|
55
|
-
data: Data;
|
|
56
|
-
layout: Layout;
|
|
57
|
-
}
|
|
58
|
-
</script>
|
|
59
|
-
|
|
60
|
-
<script lang="ts">
|
|
61
|
-
import { onMount, onDestroy, createEventDispatcher } from 'svelte';
|
|
62
|
-
import { debounce as debouncify } from 'lodash-es';
|
|
63
|
-
const browser = typeof window === 'object';
|
|
64
|
-
type not = undefined | null;
|
|
65
|
-
|
|
66
|
-
const nextFrame = browser ? requestAnimationFrame : () => void 0;
|
|
67
|
-
|
|
68
|
-
async function loadPlotly() {
|
|
69
|
-
if (!browser) return;
|
|
70
|
-
|
|
71
|
-
if (libPlotly === undefined) {
|
|
72
|
-
if (window.Plotly) {
|
|
73
|
-
libPlotly = window.Plotly;
|
|
74
|
-
} else {
|
|
75
|
-
const p = await import('plotly.js-dist');
|
|
76
|
-
if (libPlotly === undefined) libPlotly = 'default' in p ? p.default : p;
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
const DEFAULT_WIDTH = 500;
|
|
82
|
-
const DEFAULT_HEIGHT = 300;
|
|
83
|
-
|
|
84
|
-
// events
|
|
85
|
-
interface $$Events {
|
|
86
|
-
afterExport: undefined;
|
|
87
|
-
afterPlot: undefined;
|
|
88
|
-
animated: undefined;
|
|
89
|
-
animating: undefined;
|
|
90
|
-
animatingFrame: FrameAnimationEvent;
|
|
91
|
-
animationInterrupted: undefined;
|
|
92
|
-
autoSize: undefined;
|
|
93
|
-
beforeExport: undefined;
|
|
94
|
-
beforeHover: PlotMouseEvent;
|
|
95
|
-
beforePlot: BeforePlotEvent;
|
|
96
|
-
buttonClicked: ButtonClickedEvent;
|
|
97
|
-
click: PlotMouseEvent;
|
|
98
|
-
clickAnnotation: ClickAnnotationEvent;
|
|
99
|
-
deselect: undefined;
|
|
100
|
-
doubleClick: undefined;
|
|
101
|
-
framework: undefined;
|
|
102
|
-
hover: PlotHoverEvent;
|
|
103
|
-
legendClick: LegendClickEvent;
|
|
104
|
-
legendDoubleClick: LegendClickEvent;
|
|
105
|
-
react: PlotUpdateEvent;
|
|
106
|
-
redraw: undefined;
|
|
107
|
-
relayout: PlotRelayoutEvent;
|
|
108
|
-
relayouting: PlotRelayoutEvent;
|
|
109
|
-
restyle: PlotRestyleEvent;
|
|
110
|
-
selected: PlotSelectionEvent;
|
|
111
|
-
selecting: PlotSelectionEvent;
|
|
112
|
-
sliderChange: SliderChangeEvent;
|
|
113
|
-
sliderEnd: SliderEndEvent;
|
|
114
|
-
sliderStart: SliderStartEvent;
|
|
115
|
-
sunburstClick: SunburstClickEvent;
|
|
116
|
-
transitioned: undefined;
|
|
117
|
-
transitioning: undefined;
|
|
118
|
-
transitionInterrupted: undefined;
|
|
119
|
-
unhover: PlotMouseEvent;
|
|
120
|
-
update: PlotUpdateEvent;
|
|
121
|
-
webGLContextLost: undefined;
|
|
122
|
-
}
|
|
123
|
-
const events = <const>{
|
|
124
|
-
plotly_afterexport: 'afterExport',
|
|
125
|
-
plotly_afterplot: 'afterPlot',
|
|
126
|
-
plotly_animated: 'animated',
|
|
127
|
-
plotly_animating: 'animating',
|
|
128
|
-
plotly_animatingframe: 'animatingFrame',
|
|
129
|
-
plotly_animationinterrupted: 'animationInterrupted',
|
|
130
|
-
plotly_autosize: 'autoSize',
|
|
131
|
-
plotly_beforeexport: 'beforeExport',
|
|
132
|
-
plotly_beforehover: 'beforeHover',
|
|
133
|
-
plotly_beforeplot: 'beforePlot',
|
|
134
|
-
plotly_buttonclicked: 'buttonClicked',
|
|
135
|
-
plotly_click: 'click',
|
|
136
|
-
plotly_clickannotation: 'clickAnnotation',
|
|
137
|
-
plotly_deselect: 'deselect',
|
|
138
|
-
plotly_doubleclick: 'doubleClick',
|
|
139
|
-
plotly_framework: 'framework',
|
|
140
|
-
plotly_hover: 'hover',
|
|
141
|
-
plotly_legendclick: 'legendClick',
|
|
142
|
-
plotly_legenddoubleclick: 'legendDoubleClick',
|
|
143
|
-
plotly_react: 'react',
|
|
144
|
-
plotly_redraw: 'redraw',
|
|
145
|
-
plotly_relayout: 'relayout',
|
|
146
|
-
plotly_relayouting: 'relayouting',
|
|
147
|
-
plotly_restyle: 'restyle',
|
|
148
|
-
plotly_selected: 'selected',
|
|
149
|
-
plotly_selecting: 'selecting',
|
|
150
|
-
plotly_sliderchange: 'sliderChange',
|
|
151
|
-
plotly_sliderend: 'sliderEnd',
|
|
152
|
-
plotly_sliderstart: 'sliderStart',
|
|
153
|
-
plotly_sunburstclick: 'sunburstClick',
|
|
154
|
-
plotly_transitioned: 'transitioned',
|
|
155
|
-
plotly_transitioning: 'transitioning',
|
|
156
|
-
plotly_transitioninterrupted: 'transitionInterrupted',
|
|
157
|
-
plotly_unhover: 'unhover',
|
|
158
|
-
plotly_update: 'update',
|
|
159
|
-
plotly_webglcontextlost: 'webGLContextLost'
|
|
160
|
-
// TODO add all plotly_${traceType}click
|
|
161
|
-
};
|
|
162
|
-
const dispatch = createEventDispatcher<$$Events>();
|
|
163
|
-
|
|
164
|
-
// bind props
|
|
165
|
-
export let element: HTMLDivElement | not = undefined;
|
|
166
|
-
export let plot: PlotlyHTMLElement | not = undefined;
|
|
167
|
-
|
|
168
|
-
// input props
|
|
169
|
-
export let libPlotly: typeof import('plotly.js-dist') | null | undefined = undefined;
|
|
170
|
-
export let data: Data[];
|
|
171
|
-
export let layout: Partial<Layout> | undefined = undefined;
|
|
172
|
-
export let config: Partial<Config> | undefined = undefined;
|
|
173
|
-
export let fillParent: FillParent = false;
|
|
174
|
-
export let debounce: number | DebounceOptions = 0;
|
|
175
|
-
let className = '';
|
|
176
|
-
export { className as class };
|
|
177
|
-
|
|
178
|
-
// set up
|
|
179
|
-
onMount(async () => {
|
|
180
|
-
(window as any).global = window;
|
|
181
|
-
await loadPlotly();
|
|
182
|
-
});
|
|
183
|
-
|
|
184
|
-
// state props
|
|
185
|
-
let datarevision = 0;
|
|
186
|
-
let previousLib = libPlotly;
|
|
187
|
-
let previousPlot = plot;
|
|
188
|
-
let width: number = DEFAULT_WIDTH;
|
|
189
|
-
let height: number = DEFAULT_HEIGHT;
|
|
190
|
-
|
|
191
|
-
// updates
|
|
192
|
-
$: debounceWait = typeof debounce === 'object' ? debounce.wait : debounce ?? 0;
|
|
193
|
-
$: debounceOptions = typeof debounce === 'object' ? debounce : {};
|
|
194
|
-
$: data, (datarevision = (datarevision + 1) % 1000);
|
|
195
|
-
$: layout_ = { datarevision, width, height, ...layout };
|
|
196
|
-
$: config_ = { displaylogo: false, ...config };
|
|
197
|
-
$: draw(libPlotly, element, data, layout_, config_);
|
|
198
|
-
$: {
|
|
199
|
-
if (element && previousLib !== libPlotly) {
|
|
200
|
-
previousLib?.purge(element);
|
|
201
|
-
plot = undefined;
|
|
202
|
-
}
|
|
203
|
-
previousLib = libPlotly;
|
|
204
|
-
loadPlotly();
|
|
205
|
-
}
|
|
206
|
-
$: if (previousPlot !== plot) {
|
|
207
|
-
for (const [plotlyEvent, svelteEvent] of Object.entries(events)) {
|
|
208
|
-
previousPlot?.removeAllListeners?.(plotlyEvent);
|
|
209
|
-
plot?.on(plotlyEvent as any, (e: any) => dispatch(svelteEvent, e));
|
|
210
|
-
}
|
|
211
|
-
previousPlot = plot;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
const drawUndebounced = (
|
|
215
|
-
lib: typeof libPlotly,
|
|
216
|
-
e: HTMLDivElement | not,
|
|
217
|
-
d: Data[],
|
|
218
|
-
l: Partial<Layout>,
|
|
219
|
-
c: Partial<Config>
|
|
220
|
-
) => {
|
|
221
|
-
if (e) lib?.react(e, d, l, c).then(p => (plot = p));
|
|
222
|
-
};
|
|
223
|
-
|
|
224
|
-
$: draw = debouncify(drawUndebounced, debounceWait, debounceOptions);
|
|
225
|
-
|
|
226
|
-
// destroy
|
|
227
|
-
onDestroy(() => element && libPlotly?.purge(element));
|
|
228
|
-
|
|
229
|
-
// autosizing
|
|
230
|
-
$: fillParent, nextFrame(onResize);
|
|
231
|
-
$: fillParentWidth = fillParent === true || fillParent === 'width';
|
|
232
|
-
$: fillParentHeight = fillParent === true || fillParent === 'height';
|
|
233
|
-
$: parent = element?.parentElement;
|
|
234
|
-
let lastParent: typeof parent = null;
|
|
235
|
-
$: {
|
|
236
|
-
parentMounted(parent);
|
|
237
|
-
parentUnmounted(lastParent);
|
|
238
|
-
lastParent = parent;
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
let resizeObserver: ResizeObserver | not;
|
|
242
|
-
onMount(() => (resizeObserver = new ResizeObserver(onResize)));
|
|
243
|
-
const parentMounted = (parent: Element | not) => parent && resizeObserver?.observe(parent);
|
|
244
|
-
const parentUnmounted = (parent: Element | not) => parent && resizeObserver?.unobserve(parent);
|
|
245
|
-
|
|
246
|
-
function onResize() {
|
|
247
|
-
if (!parent || !element) return;
|
|
248
|
-
|
|
249
|
-
const { offsetHeight, offsetWidth } = parent;
|
|
250
|
-
const { paddingLeft, paddingTop, paddingRight, paddingBottom } =
|
|
251
|
-
window.getComputedStyle(parent);
|
|
252
|
-
|
|
253
|
-
const maxWidth = offsetWidth - parseInt(paddingLeft) - parseInt(paddingRight);
|
|
254
|
-
const maxHeight = offsetHeight - parseInt(paddingTop) - parseInt(paddingRight);
|
|
255
|
-
|
|
256
|
-
width = fillParentWidth ? maxWidth : DEFAULT_WIDTH;
|
|
257
|
-
height = fillParentHeight ? maxHeight : DEFAULT_HEIGHT;
|
|
258
|
-
}
|
|
259
|
-
</script>
|
|
260
|
-
|
|
261
|
-
<div
|
|
262
|
-
class={className}
|
|
263
|
-
class:fillParent
|
|
264
|
-
class:fillParentWidth
|
|
265
|
-
class:fillParentHeight
|
|
266
|
-
bind:this={element}
|
|
267
|
-
/>
|
|
268
|
-
|
|
269
|
-
<style lang="scss">
|
|
270
|
-
.fillParent {
|
|
271
|
-
overflow: visible;
|
|
272
|
-
}
|
|
273
|
-
.fillParentWidth {
|
|
274
|
-
width: 0 !important;
|
|
275
|
-
max-width: 0 !important;
|
|
276
|
-
}
|
|
277
|
-
.fillParentHeight {
|
|
278
|
-
height: 0 !important;
|
|
279
|
-
max-height: 0 !important;
|
|
280
|
-
}
|
|
281
|
-
</style>
|
package/src/routes/index.svelte
DELETED
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import Plot from '$lib/Plot.svelte';
|
|
3
|
-
import type { Data, FillParent, DebounceOptions, Config } from '$lib/Plot.svelte';
|
|
4
|
-
|
|
5
|
-
// FA icons borrowed for testing purposes only
|
|
6
|
-
const MAXIMIZE_ICON = {
|
|
7
|
-
width: 448,
|
|
8
|
-
height: 512,
|
|
9
|
-
path: 'M447.1 319.1v135.1c0 13.26-10.75 23.1-23.1 23.1h-135.1c-12.94 0-24.61-7.781-29.56-19.75c-4.906-11.1-2.203-25.72 6.937-34.87l30.06-30.06L224 323.9l-71.43 71.44l30.06 30.06c9.156 9.156 11.91 22.91 6.937 34.87C184.6 472.2 172.9 479.1 160 479.1H24c-13.25 0-23.1-10.74-23.1-23.1v-135.1c0-12.94 7.781-24.61 19.75-29.56C23.72 288.8 27.88 288 32 288c8.312 0 16.5 3.242 22.63 9.367l30.06 30.06l71.44-71.44L84.69 184.6L54.63 214.6c-9.156 9.156-22.91 11.91-34.87 6.937C7.798 216.6 .0013 204.9 .0013 191.1v-135.1c0-13.26 10.75-23.1 23.1-23.1h135.1c12.94 0 24.61 7.781 29.56 19.75C191.2 55.72 191.1 59.87 191.1 63.1c0 8.312-3.237 16.5-9.362 22.63L152.6 116.7l71.44 71.44l71.43-71.44l-30.06-30.06c-9.156-9.156-11.91-22.91-6.937-34.87c4.937-11.95 16.62-19.75 29.56-19.75h135.1c13.26 0 23.1 10.75 23.1 23.1v135.1c0 12.94-7.781 24.61-19.75 29.56c-11.1 4.906-25.72 2.203-34.87-6.937l-30.06-30.06l-71.43 71.43l71.44 71.44l30.06-30.06c9.156-9.156 22.91-11.91 34.87-6.937C440.2 295.4 447.1 307.1 447.1 319.1z'
|
|
10
|
-
};
|
|
11
|
-
const MINIMIZE_ICON = {
|
|
12
|
-
width: 512,
|
|
13
|
-
height: 512,
|
|
14
|
-
path: 'M200 287.1H64c-12.94 0-24.62 7.797-29.56 19.75c-4.969 11.97-2.219 25.72 6.937 34.87l30.06 30.06l-62.06 62.07c-12.49 12.5-12.5 32.75-.0012 45.25l22.62 22.62c12.5 12.5 32.76 12.5 45.26 .0012l62.06-62.07l30.06 30.06c6.125 6.125 14.31 9.375 22.62 9.375c4.125 0 8.281-.7969 12.25-2.437c11.97-4.953 19.75-16.62 19.75-29.56V311.1C224 298.7 213.3 287.1 200 287.1zM312 224h135.1c12.94 0 24.62-7.797 29.56-19.75c4.969-11.97 2.219-25.72-6.937-34.87l-30.06-30.06l62.06-62.07c12.5-12.5 12.5-32.76 .0003-45.26l-22.62-22.62c-12.5-12.5-32.76-12.5-45.26-.0003l-62.06 62.07l-30.06-30.06c-9.156-9.141-22.87-11.84-34.87-6.937C295.8 39.39 288 51.06 288 64v135.1C288 213.3 298.7 224 312 224zM204.3 34.44C192.3 29.47 178.5 32.22 169.4 41.38L139.3 71.44L77.25 9.374C64.75-3.123 44.49-3.123 31.1 9.374l-22.63 22.63c-12.49 12.49-12.49 32.75 .0018 45.25l62.07 62.06L41.38 169.4C35.25 175.5 32 183.7 32 192c0 4.125 .7969 8.281 2.438 12.25C39.39 216.2 51.07 224 64 224h135.1c13.25 0 23.1-10.75 23.1-23.1V64C224 51.06 216.2 39.38 204.3 34.44zM440.6 372.7l30.06-30.06c9.141-9.156 11.84-22.88 6.938-34.87C472.6 295.8 460.9 287.1 448 287.1h-135.1c-13.25 0-23.1 10.75-23.1 23.1v135.1c0 12.94 7.797 24.62 19.75 29.56c11.97 4.969 25.72 2.219 34.87-6.937l30.06-30.06l62.06 62.06c12.5 12.5 32.76 12.5 45.26 .0002l22.62-22.62c12.5-12.5 12.5-32.76 .0002-45.26L440.6 372.7z'
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
let y0 = 1;
|
|
18
|
-
let useDefaultLib = true;
|
|
19
|
-
let fillParent: FillParent = false;
|
|
20
|
-
let debounce: DebounceOptions | number | undefined;
|
|
21
|
-
|
|
22
|
-
let fullscreen = false;
|
|
23
|
-
$: {
|
|
24
|
-
if (fullscreen) fillParent = true;
|
|
25
|
-
else fillParent = false;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
let data: Data[];
|
|
29
|
-
$: data = [
|
|
30
|
-
{
|
|
31
|
-
x: [1, 2, 3, 4, 5],
|
|
32
|
-
y: [y0, 2, 4, 8, 16]
|
|
33
|
-
}
|
|
34
|
-
];
|
|
35
|
-
|
|
36
|
-
let config: Partial<Config>;
|
|
37
|
-
$: config = {
|
|
38
|
-
modeBarButtonsToAdd: [
|
|
39
|
-
{
|
|
40
|
-
name: 'fullscreen',
|
|
41
|
-
title: fullscreen ? 'Disable Fullscreen' : 'Enable Fullscreen',
|
|
42
|
-
icon: fullscreen ? MINIMIZE_ICON : MAXIMIZE_ICON,
|
|
43
|
-
click: () => (fullscreen = !fullscreen)
|
|
44
|
-
}
|
|
45
|
-
]
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
function addData() {
|
|
49
|
-
data.push({
|
|
50
|
-
x: [1, 2, 3, 4, 5],
|
|
51
|
-
y: Array(5)
|
|
52
|
-
.fill(0)
|
|
53
|
-
.map(_ => 10 * Math.random())
|
|
54
|
-
});
|
|
55
|
-
data = data;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
function changeY0() {
|
|
59
|
-
y0++;
|
|
60
|
-
}
|
|
61
|
-
</script>
|
|
62
|
-
|
|
63
|
-
<Plot
|
|
64
|
-
{data}
|
|
65
|
-
{fillParent}
|
|
66
|
-
{debounce}
|
|
67
|
-
{config}
|
|
68
|
-
layout={{
|
|
69
|
-
margin: { t: 0 }
|
|
70
|
-
}}
|
|
71
|
-
libPlotly={useDefaultLib ? undefined : null}
|
|
72
|
-
on:click={console.log}
|
|
73
|
-
on:relayout={console.log}
|
|
74
|
-
/>
|
|
75
|
-
|
|
76
|
-
<div class="controls">
|
|
77
|
-
<button on:click={addData}>Add trace</button>
|
|
78
|
-
<button on:click={changeY0}>Increase y<sub>0</sub></button>
|
|
79
|
-
<button on:click={() => (useDefaultLib = !useDefaultLib)}>Swap lib</button>
|
|
80
|
-
<button on:click={() => (fillParent = false)}>Fixed size</button>
|
|
81
|
-
<button on:click={() => (fillParent = true)}>Fill parent</button>
|
|
82
|
-
<button on:click={() => (fillParent = 'width')}>Fill width</button>
|
|
83
|
-
<button on:click={() => (fillParent = 'height')}>Fill height</button>
|
|
84
|
-
<button on:click={() => (debounce = undefined)}>Don't debounce</button>
|
|
85
|
-
<button on:click={() => (debounce = 500)}>Debounce 500ms</button>
|
|
86
|
-
<button on:click={() => (debounce = { wait: 500, maxWait: 2000 })}
|
|
87
|
-
>Debounce 500ms, max wait 2s</button
|
|
88
|
-
>
|
|
89
|
-
</div>
|
|
90
|
-
|
|
91
|
-
<style lang="scss">
|
|
92
|
-
:global(html, body, body > div) {
|
|
93
|
-
padding: 0;
|
|
94
|
-
margin: 0;
|
|
95
|
-
width: 100vw;
|
|
96
|
-
height: 100vh;
|
|
97
|
-
}
|
|
98
|
-
.controls {
|
|
99
|
-
position: absolute;
|
|
100
|
-
left: 0;
|
|
101
|
-
bottom: 0;
|
|
102
|
-
}
|
|
103
|
-
</style>
|
package/src/types/plotly.d.ts
DELETED
package/static/favicon.png
DELETED
|
Binary file
|
package/svelte.config.js
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import adapter from '@sveltejs/adapter-auto';
|
|
2
|
-
import preprocess from 'svelte-preprocess';
|
|
3
|
-
|
|
4
|
-
/** @type {import('@sveltejs/kit').Config} */
|
|
5
|
-
const config = {
|
|
6
|
-
// Consult https://github.com/sveltejs/svelte-preprocess
|
|
7
|
-
// for more information about preprocessors
|
|
8
|
-
preprocess: preprocess(),
|
|
9
|
-
|
|
10
|
-
kit: {
|
|
11
|
-
adapter: adapter()
|
|
12
|
-
}
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
export default config;
|
package/tsconfig.json
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"extends": "./.svelte-kit/tsconfig.json",
|
|
3
|
-
"compilerOptions": {
|
|
4
|
-
"allowJs": true,
|
|
5
|
-
"checkJs": true,
|
|
6
|
-
"esModuleInterop": true,
|
|
7
|
-
"forceConsistentCasingInFileNames": true,
|
|
8
|
-
"lib": ["es2020", "DOM"],
|
|
9
|
-
"moduleResolution": "node",
|
|
10
|
-
"module": "es2020",
|
|
11
|
-
"resolveJsonModule": true,
|
|
12
|
-
"skipLibCheck": true,
|
|
13
|
-
"sourceMap": true,
|
|
14
|
-
"strict": true,
|
|
15
|
-
"target": "es2020"
|
|
16
|
-
}
|
|
17
|
-
}
|