UNPKG

analytica-frontend-lib

Version:

Repositório público dos componentes utilizados nas plataformas da Analytica Ensino

175 lines (171 loc) 5.38 kB
import { Text_default } from "./chunk-IMCIR6TJ.mjs"; import { cn } from "./chunk-53ICLDGS.mjs"; // src/components/VerticalBarChart/VerticalBarChart.tsx import { useState, useMemo } from "react"; // src/components/VerticalBarChart/utils.ts var niceStep = (maxValue) => { const roughStep = maxValue / 4; const magnitude = Math.pow(10, Math.floor(Math.log10(roughStep))); const normalized = roughStep / magnitude; let niceNormalized; if (normalized <= 1) niceNormalized = 1; else if (normalized <= 2) niceNormalized = 2; else if (normalized <= 5) niceNormalized = 5; else niceNormalized = 10; return Math.max(1, niceNormalized * magnitude); }; var calculateTicks = (maxValue) => { if (maxValue <= 0) return [0]; const step = niceStep(maxValue); const ticks = []; for (let i = 0; i <= maxValue; i += step) { ticks.push(i); } if (ticks.at(-1) < maxValue) { ticks.push(ticks.at(-1) + step); } return ticks.reverse(); }; // src/components/VerticalBarChart/VerticalBarChart.tsx import { jsx, jsxs } from "react/jsx-runtime"; var YAxis = ({ ticks, chartHeight }) => /* @__PURE__ */ jsx( "div", { className: "flex flex-col justify-between text-right pr-2 w-12 shrink-0", style: { height: chartHeight }, "aria-hidden": "true", children: ticks.map((tick, index) => /* @__PURE__ */ jsx( Text_default, { size: "xs", weight: "medium", className: "text-text-500", children: tick.toLocaleString("pt-BR") }, `${tick}-${index}` )) } ); var Bar = ({ item, maxValue, chartHeight, barColor, isHovered, anyHovered, onMouseEnter, onMouseLeave }) => { const barHeight = maxValue === 0 ? 0 : item.value / maxValue * chartHeight; return /* @__PURE__ */ jsxs( "div", { className: "flex-1 flex flex-col items-center justify-end h-full relative group", onMouseEnter, onMouseLeave, children: [ isHovered && item.value > 0 && /* @__PURE__ */ jsxs("div", { className: "absolute bottom-full mb-2 px-2 py-1 bg-text-950 text-white text-xs rounded shadow-lg whitespace-nowrap z-10", children: [ item.value.toLocaleString("pt-BR"), /* @__PURE__ */ jsx("div", { className: "absolute top-full left-1/2 -translate-x-1/2 border-4 border-transparent border-t-text-950" }) ] }), /* @__PURE__ */ jsx( "div", { "data-testid": `bar-${item.label}`, className: "w-full max-w-[40px] rounded-t transition-all duration-300 cursor-pointer", style: { height: `${barHeight / chartHeight * 100}%`, backgroundColor: barColor, minHeight: item.value > 0 ? "4px" : "0", opacity: !anyHovered || isHovered ? 1 : 0.5 }, "aria-label": `${item.label}: ${item.value}` } ) ] } ); }; var XAxisLabels = ({ data }) => ( // ml-12 (48px) matches w-12 on YAxis for alignment /* @__PURE__ */ jsx("div", { className: "flex gap-1 ml-12", children: data.map((item) => /* @__PURE__ */ jsx("div", { className: "flex-1 text-center", children: /* @__PURE__ */ jsx( Text_default, { size: "xs", className: "text-text-500", "data-testid": `label-${item.label}`, children: item.label } ) }, item.label)) }) ); var VerticalBarChart = ({ data, title, chartHeight = 200, barColor = "#4a7c59", className, ...props }) => { const [hoveredIndex, setHoveredIndex] = useState(null); const maxValue = Math.max(...data.map((item) => item.value), 0); const yAxisTicks = useMemo(() => calculateTicks(maxValue), [maxValue]); const chartMaxValue = yAxisTicks[0] || maxValue || 1; return /* @__PURE__ */ jsxs( "div", { className: cn( "flex flex-col gap-4 bg-background border border-border-50 rounded-xl p-5", className ), "aria-label": title, ...props, children: [ /* @__PURE__ */ jsx( Text_default, { as: "h3", size: "lg", weight: "bold", className: "text-text-950 tracking-[0.2px]", children: title } ), /* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [ /* @__PURE__ */ jsx(YAxis, { ticks: yAxisTicks, chartHeight }), /* @__PURE__ */ jsx( "div", { className: "flex-1 flex items-end gap-1 border-l border-b border-border-100", style: { height: chartHeight }, children: data.map((item, index) => /* @__PURE__ */ jsx( Bar, { item, maxValue: chartMaxValue, chartHeight, barColor, isHovered: hoveredIndex === index, anyHovered: hoveredIndex !== null, onMouseEnter: () => setHoveredIndex(index), onMouseLeave: () => setHoveredIndex(null) }, `${item.label}-${index}` )) } ) ] }), /* @__PURE__ */ jsx(XAxisLabels, { data }) ] } ); }; var VerticalBarChart_default = VerticalBarChart; export { VerticalBarChart, VerticalBarChart_default }; //# sourceMappingURL=chunk-4HKNGGCT.mjs.map