@vitessce/vega 2.0.3 → 3.0.1

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.
@@ -0,0 +1,2 @@
1
+ export { Vega as default } from "react-vega";
2
+ //# sourceMappingURL=ReactVega.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ReactVega.d.ts","sourceRoot":"","sources":["../src/ReactVega.js"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ // See https://reactjs.org/docs/code-splitting.html#named-exports
2
+ export { Vega as default } from 'react-vega';
@@ -0,0 +1,9 @@
1
+ /**
2
+ * A wrapper around the react-vega Vega component.
3
+ * @param {object} props
4
+ * @param {object} spec A vega or vega-lite spec.
5
+ * @param {object[]} data The plot data as an array of objects.
6
+ * @param {object} signalListeners Vega signal listeners. Optional.
7
+ */
8
+ export function VegaPlot(props: object): JSX.Element | null;
9
+ //# sourceMappingURL=VegaPlot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VegaPlot.d.ts","sourceRoot":"","sources":["../src/VegaPlot.js"],"names":[],"mappings":"AAsCA;;;;;;GAMG;AACH,gCALW,MAAM,sBA6EhB"}
@@ -0,0 +1,83 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import React, { Suspense, useMemo } from 'react';
3
+ import { Handler } from 'vega-tooltip';
4
+ import clsx from 'clsx';
5
+ import { useTooltipStyles } from '@vitessce/tooltip';
6
+ import ReactVega from './ReactVega.js';
7
+ import { DATASET_NAME } from './utils.js';
8
+ import { useStyles } from './styles.js';
9
+ // TODO: React.lazy is not working with Vitessce in the portal-ui.
10
+ // For now, we can work around this by not using React.lazy,
11
+ // but for performance benefits that come with lazy-loading
12
+ // we should eventually try to resolve this issue.
13
+ // const ReactVega = React.lazy(() => import('./ReactVega'));
14
+ function isVega(spec) {
15
+ return spec.$schema === 'https://vega.github.io/schema/vega/v5.json';
16
+ }
17
+ function renderTooltipContents(tooltipText) {
18
+ const tableRows = Object.entries(tooltipText)
19
+ .map(([key, value]) => (`<tr key=${key}>
20
+ <th>${key}</th>
21
+ <td>${value}</td>
22
+ </tr>`))
23
+ .join('');
24
+ return (`<table>
25
+ <tbody>
26
+ ${tableRows}
27
+ </tbody>
28
+ </table>`);
29
+ }
30
+ /**
31
+ * A wrapper around the react-vega Vega component.
32
+ * @param {object} props
33
+ * @param {object} spec A vega or vega-lite spec.
34
+ * @param {object[]} data The plot data as an array of objects.
35
+ * @param {object} signalListeners Vega signal listeners. Optional.
36
+ */
37
+ export function VegaPlot(props) {
38
+ const { spec: partialSpec, data, getTooltipText, signalListeners, } = props;
39
+ // eslint-disable-next-line no-unused-vars
40
+ const classes = useStyles();
41
+ const tooltipClasses = useTooltipStyles();
42
+ const tooltipHandler = useMemo(() => {
43
+ if (typeof getTooltipText === 'function') {
44
+ const tooltipConfig = {
45
+ theme: 'custom',
46
+ offsetX: 10,
47
+ offsetY: 10,
48
+ // Use table element to match packages/tooltip/TooltipContent implementation.
49
+ formatTooltip: tooltipText => `
50
+ <div class="${clsx(classes.tooltipContainer, tooltipClasses.tooltipContent)}">
51
+ ${renderTooltipContents(tooltipText)}
52
+ </div>
53
+ `,
54
+ };
55
+ const handlerInstance = new Handler(tooltipConfig);
56
+ const originalCall = handlerInstance.call;
57
+ handlerInstance.call = (handler, event, item, value) => {
58
+ if (item && item.datum && value) {
59
+ const tooltipText = getTooltipText(item);
60
+ originalCall.call(this, handler, event, item, tooltipText);
61
+ }
62
+ else {
63
+ originalCall.call(this, handler, event, item, value);
64
+ }
65
+ };
66
+ return handlerInstance.call;
67
+ }
68
+ return false;
69
+ }, [getTooltipText, classes.tooltipContainer, tooltipClasses.tooltipContent]);
70
+ const spec = useMemo(() => ({
71
+ ...partialSpec,
72
+ data: (isVega(partialSpec)
73
+ ? [
74
+ { name: DATASET_NAME },
75
+ ...partialSpec.data,
76
+ ]
77
+ : { name: DATASET_NAME }),
78
+ }), [partialSpec]);
79
+ const vegaComponent = useMemo(() => (_jsx(ReactVega, { spec: spec, data: {
80
+ [DATASET_NAME]: data,
81
+ }, signalListeners: signalListeners, tooltip: tooltipHandler, renderer: "canvas", scaleFactor: 3 })), [spec, data, signalListeners, tooltipHandler]);
82
+ return (spec && data && data.length > 0 ? (_jsx(Suspense, { fallback: _jsx("div", { children: "Loading..." }), children: vegaComponent })) : null);
83
+ }
@@ -0,0 +1,3 @@
1
+ export { VegaPlot } from "./VegaPlot.js";
2
+ export { VEGA_THEMES, DATASET_NAME } from "./utils.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.js"],"names":[],"mappings":""}
package/dist-tsc/index.js CHANGED
@@ -1,2 +1,2 @@
1
- export { VegaPlot, DATASET_NAME } from './VegaPlot';
2
- export { VEGA_THEMES } from './utils';
1
+ export { VegaPlot } from './VegaPlot.js';
2
+ export { VEGA_THEMES, DATASET_NAME } from './utils.js';
@@ -0,0 +1,2 @@
1
+ export const useStyles: (props?: any) => import("@material-ui/core/styles/withStyles").ClassNameMap<"@global">;
2
+ //# sourceMappingURL=styles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../src/styles.js"],"names":[],"mappings":"AAEA,+GAgBI"}
@@ -0,0 +1,18 @@
1
+ import { makeStyles } from '@material-ui/core';
2
+ export const useStyles = makeStyles(theme => ({
3
+ '@global': {
4
+ '#vg-tooltip-element.vg-tooltip.custom-theme': {
5
+ boxShadow: '0px 2px 4px -1px rgba(0,0,0,0.2),0px 4px 5px 0px rgba(0,0,0,0.14),0px 1px 10px 0px rgba(0,0,0,0.12)',
6
+ padding: '0px',
7
+ backgroundColor: theme.palette.gridLayoutBackground,
8
+ color: theme.palette.secondaryForeground,
9
+ border: 'none',
10
+ opacity: 0.9,
11
+ fontSize: '12px',
12
+ borderRadius: '4px',
13
+ '& > div': {
14
+ backgroundColor: 'transparent',
15
+ },
16
+ },
17
+ },
18
+ }));
@@ -0,0 +1,27 @@
1
+ export namespace VEGA_THEMES {
2
+ namespace dark {
3
+ const background: null;
4
+ namespace title {
5
+ const color: string;
6
+ }
7
+ const style: {
8
+ 'guide-label': {
9
+ fill: string;
10
+ };
11
+ 'guide-title': {
12
+ fill: string;
13
+ };
14
+ };
15
+ namespace axis {
16
+ const domainColor: string;
17
+ const gridColor: string;
18
+ const tickColor: string;
19
+ }
20
+ }
21
+ namespace light {
22
+ const background_1: null;
23
+ export { background_1 as background };
24
+ }
25
+ }
26
+ export const DATASET_NAME: "table";
27
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AA8BA,mCAAoC"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Vega-Lite themes that can be passed to the `config` property
3
+ * of the vega-lite spec.
4
+ */
5
+ export const VEGA_THEMES = {
6
+ dark: {
7
+ // The vega-themes dark theme.
8
+ // Reference: https://github.com/vega/vega-themes/blob/master/src/theme-dark.ts
9
+ background: null,
10
+ title: { color: '#fff' },
11
+ style: {
12
+ 'guide-label': {
13
+ fill: '#fff',
14
+ },
15
+ 'guide-title': {
16
+ fill: '#fff',
17
+ },
18
+ },
19
+ axis: {
20
+ domainColor: '#fff',
21
+ gridColor: '#888',
22
+ tickColor: '#fff',
23
+ },
24
+ },
25
+ light: {
26
+ // The default vega theme.
27
+ background: null,
28
+ },
29
+ };
30
+ export const DATASET_NAME = 'table';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vitessce/vega",
3
- "version": "2.0.3",
3
+ "version": "3.0.1",
4
4
  "author": "Gehlenborg Lab",
5
5
  "homepage": "http://vitessce.io",
6
6
  "repository": {
@@ -8,28 +8,39 @@
8
8
  "url": "git+https://github.com/vitessce/vitessce.git"
9
9
  },
10
10
  "license": "MIT",
11
- "main": "dist/index.mjs",
11
+ "type": "module",
12
+ "main": "dist/index.js",
12
13
  "files": [
14
+ "src",
13
15
  "dist",
14
- "src"
16
+ "dist-tsc"
15
17
  ],
16
18
  "dependencies": {
17
19
  "@material-ui/core": "~4.12.3",
20
+ "clsx": "^1.1.1",
18
21
  "react-vega": "^7.4.4",
19
22
  "vega": "^5.21.0",
20
23
  "vega-lite": "^5.1.1",
21
- "vega-tooltip": "^0.27.0"
24
+ "vega-tooltip": "^0.27.0",
25
+ "@vitessce/tooltip": "3.0.1"
22
26
  },
23
27
  "devDependencies": {
24
28
  "react": "^18.0.0",
25
- "vite": "^3.0.0",
26
- "vitest": "^0.23.4"
29
+ "vite": "^4.3.0",
30
+ "vitest": "^0.32.2"
27
31
  },
28
32
  "peerDependencies": {
29
33
  "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
30
34
  },
31
35
  "scripts": {
32
36
  "bundle": "pnpm exec vite build -c ../../scripts/vite.config.js",
33
- "test": "pnpm exec vitest --run -r ../../ --dir ."
37
+ "test": "pnpm exec vitest --run"
38
+ },
39
+ "module": "dist/index.js",
40
+ "exports": {
41
+ ".": {
42
+ "types": "./dist-tsc/index.d.ts",
43
+ "import": "./dist/index.js"
44
+ }
34
45
  }
35
46
  }
package/src/VegaPlot.js CHANGED
@@ -1,6 +1,11 @@
1
1
  import React, { Suspense, useMemo } from 'react';
2
2
  import { Handler } from 'vega-tooltip';
3
- import ReactVega from './ReactVega';
3
+ import clsx from 'clsx';
4
+ import { useTooltipStyles } from '@vitessce/tooltip';
5
+ import ReactVega from './ReactVega.js';
6
+ import { DATASET_NAME } from './utils.js';
7
+ import { useStyles } from './styles.js';
8
+
4
9
 
5
10
  // TODO: React.lazy is not working with Vitessce in the portal-ui.
6
11
  // For now, we can work around this by not using React.lazy,
@@ -8,12 +13,29 @@ import ReactVega from './ReactVega';
8
13
  // we should eventually try to resolve this issue.
9
14
  // const ReactVega = React.lazy(() => import('./ReactVega'));
10
15
 
11
- export const DATASET_NAME = 'table';
12
-
13
16
  function isVega(spec) {
14
17
  return spec.$schema === 'https://vega.github.io/schema/vega/v5.json';
15
18
  }
16
19
 
20
+ function renderTooltipContents(tooltipText) {
21
+ const tableRows = Object.entries(tooltipText)
22
+ .map(([key, value]) => (
23
+ `<tr key=${key}>
24
+ <th>${key}</th>
25
+ <td>${value}</td>
26
+ </tr>`
27
+ ))
28
+ .join('');
29
+
30
+ return (
31
+ `<table>
32
+ <tbody>
33
+ ${tableRows}
34
+ </tbody>
35
+ </table>`
36
+ );
37
+ }
38
+
17
39
  /**
18
40
  * A wrapper around the react-vega Vega component.
19
41
  * @param {object} props
@@ -25,9 +47,43 @@ export function VegaPlot(props) {
25
47
  const {
26
48
  spec: partialSpec,
27
49
  data,
50
+ getTooltipText,
28
51
  signalListeners,
29
52
  } = props;
30
53
 
54
+ // eslint-disable-next-line no-unused-vars
55
+ const classes = useStyles();
56
+ const tooltipClasses = useTooltipStyles();
57
+
58
+ const tooltipHandler = useMemo(() => {
59
+ if (typeof getTooltipText === 'function') {
60
+ const tooltipConfig = {
61
+ theme: 'custom',
62
+ offsetX: 10,
63
+ offsetY: 10,
64
+ // Use table element to match packages/tooltip/TooltipContent implementation.
65
+ formatTooltip: tooltipText => `
66
+ <div class="${clsx(classes.tooltipContainer, tooltipClasses.tooltipContent)}">
67
+ ${renderTooltipContents(tooltipText)}
68
+ </div>
69
+ `,
70
+ };
71
+
72
+ const handlerInstance = new Handler(tooltipConfig);
73
+ const originalCall = handlerInstance.call;
74
+ handlerInstance.call = (handler, event, item, value) => {
75
+ if (item && item.datum && value) {
76
+ const tooltipText = getTooltipText(item);
77
+ originalCall.call(this, handler, event, item, tooltipText);
78
+ } else {
79
+ originalCall.call(this, handler, event, item, value);
80
+ }
81
+ };
82
+ return handlerInstance.call;
83
+ }
84
+ return false;
85
+ }, [getTooltipText, classes.tooltipContainer, tooltipClasses.tooltipContent]);
86
+
31
87
  const spec = useMemo(() => ({
32
88
  ...partialSpec,
33
89
  data: (isVega(partialSpec)
@@ -46,11 +102,11 @@ export function VegaPlot(props) {
46
102
  [DATASET_NAME]: data,
47
103
  }}
48
104
  signalListeners={signalListeners}
49
- tooltip={new Handler().call}
105
+ tooltip={tooltipHandler}
50
106
  renderer="canvas"
51
107
  scaleFactor={3}
52
108
  />
53
- ), [spec, data, signalListeners]);
109
+ ), [spec, data, signalListeners, tooltipHandler]);
54
110
 
55
111
  return (
56
112
  spec && data && data.length > 0 ? (
package/src/index.js CHANGED
@@ -1,2 +1,2 @@
1
- export { VegaPlot, DATASET_NAME } from './VegaPlot';
2
- export { VEGA_THEMES } from './utils';
1
+ export { VegaPlot } from './VegaPlot.js';
2
+ export { VEGA_THEMES, DATASET_NAME } from './utils.js';
package/src/styles.js ADDED
@@ -0,0 +1,19 @@
1
+ import { makeStyles } from '@material-ui/core';
2
+
3
+ export const useStyles = makeStyles(theme => ({
4
+ '@global': {
5
+ '#vg-tooltip-element.vg-tooltip.custom-theme': {
6
+ boxShadow: '0px 2px 4px -1px rgba(0,0,0,0.2),0px 4px 5px 0px rgba(0,0,0,0.14),0px 1px 10px 0px rgba(0,0,0,0.12)',
7
+ padding: '0px',
8
+ backgroundColor: theme.palette.gridLayoutBackground,
9
+ color: theme.palette.secondaryForeground,
10
+ border: 'none',
11
+ opacity: 0.9,
12
+ fontSize: '12px',
13
+ borderRadius: '4px',
14
+ '& > div': {
15
+ backgroundColor: 'transparent',
16
+ },
17
+ },
18
+ },
19
+ }));
package/src/utils.js CHANGED
@@ -27,3 +27,5 @@ export const VEGA_THEMES = {
27
27
  background: null,
28
28
  },
29
29
  };
30
+
31
+ export const DATASET_NAME = 'table';