Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 14 additions & 5 deletions packages/visualizations-react/src/components/ReactImpl.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,16 @@ export function wrap<Data, Options, ComponentClass extends BaseComponent<Data, O
});
const [lastTag, setLastTag] = useState(tag);

// Throw errors coming from Svelte that cannot be caught by react error boundary
// FIXME: a better solution would be to implement a global error boundary in svelte when it will be available
const [onError, setOnError] = useState<string | null>(null);

useEffect(() => {
if (onError) {
throw onError;
}
}, [onError]);

// Update data (put before creating the component to skip the initial render)
useEffect(() => {
componentRef.current?.updateData(data);
Expand All @@ -49,11 +59,10 @@ export function wrap<Data, Options, ComponentClass extends BaseComponent<Data, O
useEffect(() => {
const container = containerRef.current;
if (container) {
const component = new ComponentConstructor(
container,
initialState.data,
initialState.options
);
const component = new ComponentConstructor(container, initialState.data, {
...initialState.options,
setOnError,
});
componentRef.current = component;
return () => {
component.destroy();
Expand Down
25 changes: 22 additions & 3 deletions packages/visualizations/src/components/Chart/Chart.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,37 @@
let dataFrame: DataFrame = [];
let series: ChartSeries[] = [];
let { labelColumn } = options;
const { setOnError } = options;

// Function to handle chart creation errors
function tryCreateChart(ctx: CanvasRenderingContext2D, config: ChartConfiguration) {
try {
return new Chart(ctx, config);
} catch (err: any) {
setOnError?.(err.toString());
return undefined;
}
}

// Hook to handle chart lifecycle
function chartJs(node: HTMLCanvasElement, config: ChartConfiguration) {
const ctx = node.getContext('2d');
if (!ctx) throw new Error('Failed to get canvas context');
const chart = new Chart(ctx, config);
const chart: Chart | undefined = tryCreateChart(ctx, config);
return {
update() {
chart.update();
try {
chart?.update();
} catch (err: any) {
setOnError?.(err.toString());
}
},
destroy() {
chart.destroy();
try {
chart?.destroy();
} catch (err: any) {
setOnError?.(err.toString());
}
},
};
}
Expand Down
2 changes: 2 additions & 0 deletions packages/visualizations/src/components/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ export interface ChartOptions {
ariaLabel: string;
/** Link button to source */
source?: Source;
/** Error setter to send error from svelte to another framework */
setOnError?: (error: string) => string;
}

export interface Source {
Expand Down