feat: time event chart legend add some interaction

This commit is contained in:
moonrailgun 2024-10-04 22:01:43 +08:00
parent f3d8f5543d
commit 4b7877155f
2 changed files with 31 additions and 4 deletions

View File

@ -1,6 +1,6 @@
import { useTheme } from '../hooks/useTheme';
import { DateUnit } from '@tianji/shared';
import React from 'react';
import React, { useState } from 'react';
import { formatDateWithUnit } from '../utils/date';
import {
Area,
@ -42,6 +42,7 @@ export const TimeEventChart: React.FC<{
const lineDasharray = strokeDasharray.find((s) => s.name === name);
return lineDasharray ? lineDasharray.strokeDasharray : undefined;
};
const [selectedItem, setSelectedItem] = useState<string[]>(['pv', 'uv']);
return (
<ChartContainer config={chartConfig}>
@ -65,10 +66,27 @@ export const TimeEventChart: React.FC<{
tickFormatter={(text) => formatDateWithUnit(text, props.unit)}
/>
<YAxis mirror />
<ChartLegend content={<ChartLegendContent />} />
<ChartLegend
content={
<ChartLegendContent
selectedItem={selectedItem}
onItemClick={(item) => {
setSelectedItem((selected) => {
if (selected.includes(item.value)) {
return selected.filter((s) => s !== item.value);
} else {
return [...selected, item.value];
}
});
}}
/>
}
/>
<CartesianGrid vertical={false} />
<ChartTooltip content={<ChartTooltipContent />} />
<Area
hide={!selectedItem.includes('pv')}
type="monotone"
dataKey="pv"
stroke={colors.chart.pv}
@ -78,7 +96,9 @@ export const TimeEventChart: React.FC<{
strokeDasharray={getStrokeDasharray('pv')}
onAnimationEnd={handleAnimationEnd}
/>
<Area
hide={!selectedItem.includes('uv')}
type="monotone"
dataKey="uv"
stroke={colors.chart.uv}

View File

@ -261,16 +261,20 @@ ChartTooltipContent.displayName = "ChartTooltip"
const ChartLegend = RechartsPrimitive.Legend
type Payload = NonNullable<RechartsPrimitive.LegendProps['payload']>[number]
const ChartLegendContent = React.forwardRef<
HTMLDivElement,
React.ComponentProps<"div"> &
Pick<RechartsPrimitive.LegendProps, "payload" | "verticalAlign"> & {
hideIcon?: boolean
nameKey?: string
} & {
selectedItem?: string[]
onItemClick?: (item: Payload) => void
}
>(
(
{ className, hideIcon = false, payload, verticalAlign = "bottom", nameKey },
{ className, hideIcon = false, payload, verticalAlign = "bottom", nameKey, selectedItem, onItemClick },
ref
) => {
const { config } = useChart()
@ -296,8 +300,11 @@ const ChartLegendContent = React.forwardRef<
<div
key={item.value}
className={cn(
"flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3 [&>svg]:text-muted-foreground"
"flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3 [&>svg]:text-muted-foreground",
typeof onItemClick === 'function' && 'cursor-pointer',
selectedItem?.includes(item.value) && 'font-bold',
)}
onClick={() => onItemClick?.(item)}
>
{itemConfig?.icon && !hideIcon ? (
<itemConfig.icon />