feat: time event chart legend add some interaction
This commit is contained in:
parent
f3d8f5543d
commit
4b7877155f
@ -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}
|
||||
|
@ -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 />
|
||||
|
Loading…
Reference in New Issue
Block a user