source: frontend/src/components/graphs/PercentChangeAreaChart.jsx@ c0086c0

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

training graph developed

  • Property mode set to 100644
File size: 2.8 KB
Line 
1import React, { Suspense, lazy, useMemo } from "react";
2
3import { formatBucketLabel } from "../../utils/timeSeries.js";
4
5// Code-split the charting library (ApexCharts) so it doesn't bloat the initial bundle.
6const ApexChart = lazy(() => import("react-apexcharts"));
7
8export default function PercentChangeAreaChart({
9 points,
10 granularity,
11 height = 260,
12 positiveColor = "#22c55e",
13}) {
14 const series = useMemo(() => {
15 const data = (points ?? []).map((p) => ({ x: p.ts, y: Number(p.value ?? 0) }));
16 return [{ name: "% change", data }];
17 }, [points]);
18
19 const options = useMemo(() => {
20 return {
21 chart: {
22 type: "area",
23 toolbar: { show: false },
24 zoom: { enabled: false },
25 animations: { enabled: true, easing: "easeinout", speed: 450 },
26 fontFamily: "inherit",
27 foreColor: "rgba(255,255,255,0.72)",
28 },
29 stroke: {
30 curve: "smooth",
31 width: 2,
32 },
33 fill: {
34 type: "gradient",
35 gradient: {
36 shadeIntensity: 0.2,
37 opacityFrom: 0.35,
38 opacityTo: 0.05,
39 stops: [0, 90, 100],
40 },
41 },
42 dataLabels: { enabled: false },
43 grid: {
44 borderColor: "rgba(255,255,255,0.08)",
45 strokeDashArray: 4,
46 },
47 xaxis: {
48 type: "datetime",
49 labels: {
50 datetimeUTC: false,
51 formatter: (value, timestamp) => formatBucketLabel(timestamp, granularity),
52 },
53 axisBorder: { color: "rgba(255,255,255,0.10)" },
54 axisTicks: { color: "rgba(255,255,255,0.10)" },
55 },
56 yaxis: {
57 labels: {
58 formatter: (v) => `${Math.round(v)}%`,
59 },
60 },
61 tooltip: {
62 theme: "dark",
63 y: {
64 formatter: (_v, opts) => {
65 const p = points?.[opts.dataPointIndex];
66 const pct = Number(p?.value ?? 0);
67 const base = Number(p?.base ?? 0);
68 return `${pct.toFixed(1)}% (base ${Math.round(base)})`;
69 },
70 },
71 },
72 colors: [positiveColor],
73 annotations: {
74 yaxis: [
75 {
76 y: 0,
77 borderColor: "rgba(255,255,255,0.25)",
78 strokeDashArray: 4,
79 },
80 ],
81 },
82 // Color negative area differently by using a second series-like trick is overkill;
83 // we keep a single color and rely on the 0% line for readability.
84 };
85 }, [granularity, points, positiveColor]);
86
87 return (
88 <div className="w-full">
89 <Suspense
90 fallback={
91 <div className="flex items-center justify-center" style={{ height }}>
92 <span className="loading loading-spinner loading-md" />
93 </div>
94 }
95 >
96 <ApexChart options={options} series={series} type="area" height={height} />
97 </Suspense>
98 </div>
99 );
100}
101
102
103
Note: See TracBrowser for help on using the repository browser.