source: frontend/src/components/graphs/MultiPercentChangeAreaChart.jsx

Last change on this file was a8381b1, checked in by Andrej <asumanovski@…>, 2 months ago

Control center page developed

  • Property mode set to 100644
File size: 2.7 KB
Line 
1import React, { Suspense, lazy, useMemo } from "react";
2
3import { formatBucketLabel } from "../../utils/timeSeries.js";
4
5// Lazy-load ApexCharts (same as PercentChangeAreaChart)
6const ApexChart = lazy(() => import("react-apexcharts"));
7
8/**
9 * Multi-series % change area chart.
10 *
11 * seriesList: [{ name: string, points: [{ts, value}], color: string }]
12 * granularity: daily | weekly | monthly | yearly
13 */
14export default function MultiPercentChangeAreaChart({
15 seriesList,
16 granularity,
17 height = 320,
18}) {
19 const series = useMemo(() => {
20 return (seriesList ?? []).map((s) => ({
21 name: s.name,
22 data: (s.points ?? []).map((p) => ({ x: p.ts, y: Number(p.value ?? 0) })),
23 }));
24 }, [seriesList]);
25
26 const colors = useMemo(() => (seriesList ?? []).map((s) => s.color), [seriesList]);
27
28 const options = useMemo(() => {
29 return {
30 chart: {
31 type: "area",
32 stacked: false,
33 toolbar: { show: false },
34 zoom: { enabled: false },
35 animations: { enabled: true, easing: "easeinout", speed: 450 },
36 fontFamily: "inherit",
37 foreColor: "rgba(255,255,255,0.72)",
38 },
39 stroke: { curve: "smooth", width: 2 },
40 fill: {
41 type: "gradient",
42 gradient: {
43 shadeIntensity: 0.18,
44 opacityFrom: 0.22,
45 opacityTo: 0.03,
46 stops: [0, 90, 100],
47 },
48 },
49 dataLabels: { enabled: false },
50 grid: {
51 borderColor: "rgba(255,255,255,0.08)",
52 strokeDashArray: 4,
53 },
54 legend: {
55 show: false, // we render our own legend outside for better layout
56 },
57 xaxis: {
58 type: "datetime",
59 labels: {
60 datetimeUTC: false,
61 formatter: (value, timestamp) => formatBucketLabel(timestamp, granularity),
62 },
63 axisBorder: { color: "rgba(255,255,255,0.10)" },
64 axisTicks: { color: "rgba(255,255,255,0.10)" },
65 },
66 yaxis: {
67 labels: {
68 formatter: (v) => `${Math.round(v)}%`,
69 },
70 },
71 tooltip: {
72 theme: "dark",
73 y: {
74 formatter: (v) => `${Number(v ?? 0).toFixed(1)}%`,
75 },
76 },
77 colors,
78 annotations: {
79 yaxis: [
80 {
81 y: 0,
82 borderColor: "rgba(255,255,255,0.25)",
83 strokeDashArray: 4,
84 },
85 ],
86 },
87 };
88 }, [colors, granularity]);
89
90 return (
91 <div className="w-full">
92 <Suspense
93 fallback={
94 <div className="flex items-center justify-center" style={{ height }}>
95 <span className="loading loading-spinner loading-md" />
96 </div>
97 }
98 >
99 <ApexChart options={options} series={series} type="area" height={height} />
100 </Suspense>
101 </div>
102 );
103}
104
Note: See TracBrowser for help on using the repository browser.