owncast/web/pages/components/chart.tsx

132 lines
3 KiB
TypeScript
Raw Normal View History

2020-10-27 09:53:04 +03:00
import { LineChart, XAxis, YAxis, Line, Tooltip, Legend } from "recharts";
import { timeFormat } from "d3-time-format";
import useWindowSize from '../../utils/hook-windowresize';
import styles from '../../styles/styles.module.css';
2020-10-27 09:53:04 +03:00
2020-10-28 10:53:24 +03:00
interface ToolTipProps {
active?: boolean,
2020-11-12 06:39:57 +03:00
payload?: {name: string, payload: {value: string, time: Date}}[],
2020-10-29 22:39:59 +03:00
unit?: string
2020-11-01 09:17:44 +03:00
}
2020-10-28 10:53:24 +03:00
const defaultProps = {
active: false,
2020-11-01 10:01:37 +03:00
payload: Object,
unit: '',
2020-10-28 10:53:24 +03:00
};
2020-11-01 10:01:37 +03:00
interface TimedValue {
time: Date;
value: number;
2020-11-01 10:01:37 +03:00
}
2020-10-28 10:53:24 +03:00
interface ChartProps {
2020-11-01 10:01:37 +03:00
data?: TimedValue[],
title?: string,
2020-10-28 10:53:24 +03:00
color: string,
unit: string,
2020-11-01 10:01:37 +03:00
dataCollections?: any[],
2020-10-28 10:53:24 +03:00
}
function CustomizedTooltip(props: ToolTipProps) {
const { active, payload, unit } = props;
2020-10-28 10:53:24 +03:00
if (active && payload && payload[0]) {
const time = payload[0].payload ? timeFormat("%I:%M")(new Date(payload[0].payload.time)) : "";
2020-11-12 06:39:57 +03:00
const tooltipDetails = payload.map(data => {
return <div className="label" key={data.name}>
{data.payload.value}{unit} {data.name}
</div>
});
2020-10-28 10:53:24 +03:00
return (
2020-11-12 06:39:57 +03:00
<span className="custom-tooltip">
<strong>{time}</strong>
{tooltipDetails}
</span>
2020-10-28 10:53:24 +03:00
);
}
return null;
}
CustomizedTooltip.defaultProps = defaultProps;
2020-10-27 09:53:04 +03:00
export default function Chart({ data, title, color, unit, dataCollections }: ChartProps) {
2020-11-01 10:01:37 +03:00
if (!data && !dataCollections) {
return null;
}
const windowSize = useWindowSize();
const chartWidth = windowSize.width * .68;
const chartHeight = chartWidth * .333;
2020-11-01 10:01:37 +03:00
2020-10-28 10:53:24 +03:00
const timeFormatter = (tick: string) => {
return timeFormat("%I:%M")(new Date(tick));
2020-10-27 09:53:04 +03:00
};
let ticks = [];
2020-11-01 10:01:37 +03:00
if (dataCollections.length > 0) {
ticks = dataCollections[0].data?.map((collection) => {
2020-11-01 10:01:37 +03:00
return collection?.time;
})
} else if (data?.length > 0){
ticks = data?.map(item => {
2020-11-01 10:01:37 +03:00
return item?.time;
});
}
2020-11-01 09:17:44 +03:00
const line = data ? (
<Line
type="natural"
dataKey="value"
stroke={color}
dot={null}
strokeWidth={3}
legendType="square"
name={title}
/>
) : null;
2020-10-27 09:53:04 +03:00
return (
<div className={styles.lineChartContainer}>
<LineChart width={chartWidth} height={chartHeight} data={data}>
<XAxis
dataKey="time"
tickFormatter={timeFormatter}
interval="preserveStartEnd"
tickCount={5}
minTickGap={15}
domain={["dataMin", "dataMax"]}
ticks={ticks}
/>
<YAxis
dataKey="value"
interval="preserveStartEnd"
unit={unit}
domain={["dataMin", "dataMax"]}
/>
<Tooltip content={<CustomizedTooltip unit={unit} />} />
<Legend />
{line}
{dataCollections?.map((s) => (
<Line
dataKey="value"
data={s.data}
name={s.name}
key={s.name}
type="natural"
stroke={s.color}
dot={null}
strokeWidth={3}
legendType="square"
/>
))}
</LineChart>
</div>
2020-10-27 09:53:04 +03:00
);
}
2020-11-01 09:17:44 +03:00
Chart.defaultProps = {
dataCollections: [],
data: [],
title: '',
2020-11-01 09:17:44 +03:00
};