Skip to content

Commit 7a18ffb

Browse files
committed
Fix vega OnClick warning
1 parent 759a782 commit 7a18ffb

File tree

2 files changed

+62
-6
lines changed

2 files changed

+62
-6
lines changed

chartlets.js/src/lib/components/Plot.tsx

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ import { VegaLite } from "react-vega";
22

33
import { type PlotState } from "@/lib/types/state/component";
44
import { type ComponentChangeHandler } from "@/lib/types/state/event";
5+
import type { TopLevelParameter } from "vega-lite/src/spec/toplevel";
6+
import type { TopLevelSelectionParameter } from "vega-lite/src/selection";
7+
import type { Stream } from "vega-typings/types/spec/stream";
58

69
export interface PlotProps extends Omit<PlotState, "type"> {
710
onChange: ComponentChangeHandler;
@@ -11,8 +14,38 @@ export function Plot({ id, style, chart, onChange }: PlotProps) {
1114
if (!chart) {
1215
return <div id={id} style={style} />;
1316
}
17+
18+
function isTopLevelSelectionParameter(
19+
param: TopLevelParameter,
20+
): param is TopLevelSelectionParameter {
21+
return "select" in param;
22+
}
23+
24+
function isString(signal_name: string | Stream): signal_name is string {
25+
return typeof signal_name === "string";
26+
}
27+
28+
const signals: { [key: string]: string } = {};
29+
30+
chart.params?.forEach((param) => {
31+
if (isTopLevelSelectionParameter(param)) {
32+
if (
33+
typeof param.select === "object" &&
34+
"on" in param.select &&
35+
param.select.on != null
36+
) {
37+
const signal_name = param.select.on;
38+
if (isString(signal_name)) {
39+
signals[signal_name] = param.name;
40+
}
41+
}
42+
}
43+
});
44+
1445
const { datasets, ...spec } = chart;
15-
const handleSignal = (_signalName: string, value: unknown) => {
46+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
47+
// @ts-expect-error
48+
const handleClickSignal = (signalName: string, value: unknown) => {
1649
if (id) {
1750
return onChange({
1851
componentType: "Plot",
@@ -22,12 +55,37 @@ export function Plot({ id, style, chart, onChange }: PlotProps) {
2255
});
2356
}
2457
};
58+
59+
type SignalHandler = (signalName: string, value: unknown) => void;
60+
61+
// Currently, we only have click events support, but if more are required, they can be implemented and added in the map below.
62+
const signalHandlerMap: { [key: string]: SignalHandler } = {
63+
click: handleClickSignal,
64+
};
65+
66+
const createSignalListeners = (signals: { [key: string]: string }) => {
67+
const signalListeners: { [key: string]: SignalHandler } = {};
68+
Object.entries(signals).forEach(([event, signalName]) => {
69+
if (signalHandlerMap[event]) {
70+
signalListeners[signalName] = signalHandlerMap[event];
71+
} else {
72+
console.warn(
73+
"The signal " + event + " is not yet supported in chartlets.js",
74+
);
75+
}
76+
});
77+
78+
return signalListeners;
79+
};
80+
81+
const signalListeners = createSignalListeners(signals);
82+
2583
return (
2684
<VegaLite
2785
spec={spec}
2886
data={datasets}
2987
style={style}
30-
signalListeners={{ onClick: handleSignal }}
88+
signalListeners={signalListeners}
3189
actions={false}
3290
/>
3391
);

chartlets.js/src/lib/types/state/component.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { type CSSProperties } from "react";
2-
import type { VisualizationSpec } from "react-vega";
32
import { isObject } from "@/lib/utils/isObject";
3+
import type {TopLevelSpec} from "vega-lite/src/spec";
44

55
export type ComponentType =
66
| "Box"
@@ -54,9 +54,7 @@ export interface CheckboxState extends ComponentState {
5454
export interface PlotState extends ComponentState {
5555
type: "Plot";
5656
chart:
57-
| (VisualizationSpec & {
58-
datasets?: Record<string, unknown>; // Add the datasets property
59-
})
57+
| TopLevelSpec
6058
| null;
6159
}
6260

0 commit comments

Comments
 (0)