ui icon indicating copy to clipboard operation
ui copied to clipboard

[feat]: Allow `<ChartLegendContent />` to have callbacks for legend Items

Open BalduinB opened this issue 1 year ago • 0 comments

Feature description

You can pass <ChartLegend /> from Recharts the following callbacks onClick, onMouseEnter and onMouseLeave. This enables you to make the following interactive Legend.


 const [interavtiveLegend, setInteractiveLegend] = useState<State>(def ?? { hover: null });
    const handleLegendMouseEnter = ({ dataKey }: Payload) => {
        if (typeof dataKey !== "string" || !!interavtiveLegend.dataKey) return;
        if (!interavtiveLegend[dataKey]) {
            setInteractiveLegend({ ...interavtiveLegend, hover: dataKey ?? null });
        }
    };

    const handleLegendMouseLeave = () => {
        setInteractiveLegend({ ...interavtiveLegend, hover: null });
    };
    const selectBar = ({ dataKey }: Payload) => {
        if (typeof dataKey !== "string") return;
        setInteractiveLegend({
            ...interavtiveLegend,
            [dataKey]: !interavtiveLegend[dataKey],
            hover: null,
        });
    };
return (
 <ChartContainer config={chartConfig} className="mx-auto max-h-[400px]">
                <LineChart accessibilityLayer data={chartData}>
                    <ChartLegend 
                        onClick={selectBar}
                        onMouseEnter={handleLegendMouseEnter}
                        onMouseLeave={handleLegendMouseLeave}
                    />
                    <CartesianGrid vertical={false} />
                    <XAxis dataKey="date" tickLine={false} axisLine={false} tickMargin={8} />
                    <YAxis tickLine={false} axisLine={false} />
                    <ChartTooltip cursor={false} content={<ChartTooltipContent />} />
                    {Object.entries(chartConfig).map(([key, { color }]) => {
                        const isHovered = interavtiveLegend.hover === key;
                        const noneHovered = interavtiveLegend.hover === null;
                        return (
                            <Line
                                dataKey={key}
                                key={key}
                                hide={interavtiveLegend[key] === true}
                                opacity={isHovered || noneHovered ? 1 : 0.1}
                                type="monotone"
                                stroke={color}
                                fill={color}
                                strokeWidth={2}
                                dot={false}
                            />
                        );
                    })}
                </LineChart>
            </ChartContainer>
);

This enables us to toggle visibility on click and highlight a Line on Legend item hover. Using the recommended Legend Component we are missing these callbacks:

<ChartLegend
    content={
        <ChartLegendContent />
    }
/>

Affected component/components

ChartLegendContent

Additional Context

i have this problem solved locally, I would file a PR later today my API solution looks like this:

<ChartLegend
    content={
        <ChartLegendContent
            clicked={selectBar}
            mouseOver={handleLegendMouseEnter}
            mouseLeave={handleLegendMouseLeave}
        />
    }
/>

I am using different Names because this element allow all div props.

Before submitting

  • [X] I've made research efforts and searched the documentation
  • [X] I've searched for existing issues and PRs

BalduinB avatar Jul 06 '24 11:07 BalduinB