From 1354a0cbc660b590a41f1b0270a0d728e483a001 Mon Sep 17 00:00:00 2001 From: qixinbo Date: Sun, 15 Mar 2026 22:36:27 +0800 Subject: [PATCH] polish vega --- frontend/src/components/VegaChart.tsx | 55 +++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 8 deletions(-) diff --git a/frontend/src/components/VegaChart.tsx b/frontend/src/components/VegaChart.tsx index 73196fd..dff51da 100644 --- a/frontend/src/components/VegaChart.tsx +++ b/frontend/src/components/VegaChart.tsx @@ -29,14 +29,53 @@ export const VegaChart: React.FC = ({ data, spec }) => { return () => observer.disconnect(); }, []); - const vegaSpec: any = useMemo(() => ({ - $schema: typeof spec.$schema === 'string' ? spec.$schema : 'https://vega.github.io/schema/vega-lite/v5.json', - ...spec, - width: size.width > 0 ? size.width : "container", - height: size.height > 0 ? size.height : "container", - data: { values: data }, - autosize: { type: "fit", contains: "padding", resize: true }, - }), [data, size.height, size.width, spec]); + const vegaSpec: any = useMemo(() => { + // Clone spec and ensure tooltip is enabled in mark if not already specified + const baseSpec = { ...spec }; + if (typeof baseSpec.mark === 'string') { + baseSpec.mark = { type: baseSpec.mark, tooltip: true }; + } else if (typeof baseSpec.mark === 'object' && baseSpec.mark !== null) { + baseSpec.mark = { ...baseSpec.mark, tooltip: true }; + } + + // Add highlight effect: hover over an element makes others transparent + // 1. Define hover param + if (!baseSpec.params) { + baseSpec.params = [ + { + name: "highlight", + select: { type: "point", on: "mouseover", clear: "mouseout" } + } + ]; + } + + // 2. Add conditional opacity to encoding + if (!baseSpec.encoding) { + baseSpec.encoding = {}; + } + + // Only add opacity highlight if not explicitly set + if (!baseSpec.encoding.opacity) { + baseSpec.encoding.opacity = { + condition: { param: "highlight", value: 1 }, + value: 0.3 + }; + } + + // Also add cursor: pointer for marks + if (typeof baseSpec.mark === 'object' && baseSpec.mark !== null) { + (baseSpec.mark as any).cursor = "pointer"; + } + + return { + $schema: typeof spec.$schema === 'string' ? spec.$schema : 'https://vega.github.io/schema/vega-lite/v5.json', + ...baseSpec, + width: size.width > 0 ? size.width : "container", + height: size.height > 0 ? size.height : "container", + data: { values: data }, + autosize: { type: "fit", contains: "padding", resize: true }, + }; + }, [data, size.height, size.width, spec]); return (