PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.16
Yatra – Travel Booking & Tour Operator Software v3.0.16
3.0.16 3.0.15 3.0.14 3.0.14.1 3.0.14.2 3.0.12 3.0.13 3.0.11 3.0.10 3.0.9 3.0.8 3.0.7 3.0.6 3.0.5 3.0.5.1 3.0.4 3.0.3 3.0.2.9 3.0.2.7 3.0.2.8 3.0.2.6 trunk 1.0.0 2.0.0 2.0.1 All 84 releases
yatra / resources / js / components / charts / SimpleBarChart.tsx

SimpleBarChart.tsx in Yatra – Travel Booking & Tour Operator Software 3.0.16, at resources/js/components/charts/SimpleBarChart.tsx

99 lines 2.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * Simple Bar Chart Component
3 * Lightweight bar chart for displaying data
4 */
5
6 import React from "react";
7 import { __ } from "../../lib/i18n";
8
9 interface BarData {
10 label: string;
11 value: number;
12 color?: string;
13 }
14
15 interface SimpleBarChartProps {
16 data: BarData[];
17 title: string;
18 height?: number;
19 showValues?: boolean;
20 }
21
22 /**
23 * Simple Bar Chart Component
24 */
25 export const SimpleBarChart: React.FC<SimpleBarChartProps> = ({
26 data,
27 title,
28 height = 200,
29 showValues = true,
30 }) => {
31 if (!data || data.length === 0) {
32 return (
33 <div className="flex items-center justify-center h-full text-gray-500 dark:text-gray-400">
34 {__("No data available", "yatra")}
35 </div>
36 );
37 }
38
39 const maxValue = Math.max(...data.map((d) => d.value), 1);
40 const chartHeight = height - 60;
41 const defaultColors = ["#3b82f6", "#10b981", "#f59e0b", "#ef4444", "#8b5cf6"];
42
43 return (
44 <div className="w-full">
45 {title && (
46 <h3 className="text-sm font-medium text-gray-700 dark:text-gray-300 mb-4">
47 {title}
48 </h3>
49 )}
50 <div
51 className="flex items-end justify-between gap-3"
52 style={{ height: `${chartHeight}px` }}
53 >
54 {data.map((item, index) => {
55 const ratio = item.value / maxValue;
56 // Height in pixels relative to chartHeight, with a strong minimum for non-zero values
57 const barPixelHeight =
58 item.value > 0 ? Math.max(ratio * chartHeight, 24) : 0;
59 const color =
60 item.color || defaultColors[index % defaultColors.length];
61
62 return (
63 <div
64 key={index}
65 className="flex-1 flex flex-col items-center group min-w-0"
66 >
67 <div
68 className="relative w-full flex items-end justify-center mb-3"
69 style={{ height: "100%" }}
70 >
71 <div
72 className="w-3/4 max-w-[32px] rounded-t-md transition-all hover:opacity-90 relative group/bar"
73 style={{
74 height: `${barPixelHeight}px`,
75 backgroundColor: color,
76 minHeight: item.value > 0 ? "24px" : "4px",
77 }}
78 title={`${item.label}: ${item.value}`}
79 >
80 {showValues && item.value > 0 && (
81 <span className="absolute -top-7 left-1/2 transform -translate-x-1/2 text-xs font-medium text-gray-600 dark:text-gray-400 whitespace-nowrap opacity-0 group-hover/bar:opacity-100 transition-opacity">
82 {item.value}
83 </span>
84 )}
85 </div>
86 </div>
87 <span className="text-xs font-medium text-gray-500 dark:text-gray-400 text-center truncate w-full px-1">
88 {item.label}
89 </span>
90 </div>
91 );
92 })}
93 </div>
94 </div>
95 );
96 };
97
98 export default SimpleBarChart;
99