gpt-vis
uifunnelsource: ok · hit
GPT-Vis Funnel Chart
A funnel chart component for @antv/gpt-vis. Visualize progressive data reduction through stages.
npx shadcn add "https://gpt-vis.antv.vision/r/funnel.json"free
Visual style
playful
Tags auto-generated by rules on 9/24/2026 — empty means no evidence, not lack of support.
Dependencies
Bundle weight · light@antv/gpt-visclsxtailwind-merge
Files2 · source cached 10/9/2026, 4:49:34 AM
cn/block/gpt-vis/gpt-vis.tsx
'use client';
import { GPTVis as GPTVisCore, type VisualizationOptions } from '@antv/gpt-vis';
import { clsx, type ClassValue } from 'clsx';
import { useEffect, useRef, useState } from 'react';
import { twMerge } from 'tailwind-merge';
function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}
export interface GPTVisProps extends Omit<VisualizationOptions, 'container'> {
content: string | Record<string, unknown>;
className?: string;
containerStyle?: React.CSSProperties;
}
export function GPTVis({
content,
width,
height,
theme,
wrapper,
locale,
className,
containerStyle,
}: GPTVisProps) {
const containerRef = useRef<HTMLDivElement>(null);
const [instance, setInstance] = useState<GPTVisCore | null>(null);
useEffect(() => {
if (!containerRef.current) return;
const inst = new GPTVisCore({
container: containerRef.current,
width,
height,
theme,
wrapper,
locale,
});
setInstance(inst);
return () => {
inst.destroy();
setInstance(null);
};
}, [width, height, theme, wrapper, locale]);
const contentDeps = typeof content === 'string' ? content : JSON.stringify(content);
useEffect(() => {
instance?.render(content);
}, [instance, contentDeps]);
return (
<div
ref={containerRef}
className={cn('w-full min-h-[300px]', className)}
style={containerStyle}
/>
);
}
cn/block/gpt-vis/funnel.tsx
'use client';
import type { FunnelConfig } from '@antv/gpt-vis';
import { GPTVis, type GPTVisProps } from './gpt-vis';
export interface FunnelProps extends Omit<GPTVisProps, 'content'> {
config: Omit<FunnelConfig, 'type'>;
}
export function Funnel({ config, ...props }: FunnelProps) {
return <GPTVis content={{ type: 'funnel', ...config }} {...props} />;
}