DataScope26/WEB
0
1import React, { useState } from 'react'2import { Users, Percent } from 'lucide-react';3import InfoIcon from './InfoIcon.jsx';4import './BarGraph.css';5import ButtonPrimary from './ButtonPrimary.jsx';6import ButtonSecondary from './ButtonSecondary.jsx';7 8const MIN_BAR_PERCENT = 2; // ancho mínimo visible cuando el valor es 09const LABEL_INSIDE_THRESHOLD = 15; // si la barra es más angosta que esto, el número se muestra afuera10 11export default function BarGraph({ metrics, numberedAxisValueName, numberedAxisTotalName, namedAxis, infoDescription, infoTitle, title }) {12 13 // 'fraction' -> "3/10 empleados" | 'percent' -> "30%"14 const [valueFormat, setValueFormat] = useState('fraction');15 16 const data = metrics17 .filter(item => {18 // Excluir "General" y "Sin area" (default) de los gráficos19 const rawLabel = item[namedAxis];20 return rawLabel !== 'General' && rawLabel !== '\"default\"';21 })22 .map(item => {23 const rawLabel = item[namedAxis];24 const numerator = item[numberedAxisValueName];25 const denominator = item[numberedAxisTotalName];26 const percent = Number((numerator * 100) / denominator) || 0;27 28 return {29 label: rawLabel === '\"default\"' ? 'Sin area asignada' : rawLabel,30 value: percent,31 fractionLabel: `${numerator} de ${denominator} empleados`,32 percentLabel: `${Math.round(percent * 100) / 100}%`33 };34 });35 36 return (37 <>38 <div className="bar-graph-header">39 <span className="bar-graph-title">{title}</span>40 41 <div className="bar-graph-header-right">42 <div className="bar-graph-format-toggle">43 <ButtonPrimary44 type="button"45 className={`bar-graph-format-btn ${valueFormat === 'fraction' ? 'bar-graph-format-btn--active' : ''}`}46 onClick={() => setValueFormat('fraction')}47 aria-label="Mostrar como cantidad de empleados"48 title="Cantidad de empleados"49 >50 <Users size={16} strokeWidth={2} />51 </ButtonPrimary>52 <ButtonSecondary53 type="button"54 className={`bar-graph-format-btn ${valueFormat === 'percent' ? 'bar-graph-format-btn--active' : ''}`}55 onClick={() => setValueFormat('percent')}56 aria-label="Mostrar como porcentaje"57 title="Porcentaje"58 >59 <Percent size={16} strokeWidth={2} />60 </ButtonSecondary>61 </div>62 63 <InfoIcon64 title={infoTitle}65 description={infoDescription}66 />67 </div>68 </div>69 70 <div className="bar-graph-container">71 {data.map((item, index) => {72 const widthPercent = item.value <= 073 ? MIN_BAR_PERCENT74 : Math.min(item.value, 100);75 76 const labelInside = widthPercent >= LABEL_INSIDE_THRESHOLD;77 const displayLabel = valueFormat === 'percent' ? item.percentLabel : item.fractionLabel;78 79 return (80 <div className="bar-graph-row" key={index}>81 <div className="bar-graph-label">{item.label}</div>82 <div className="bar-graph-track">83 <div84 className={`bar-graph-fill ${labelInside ? 'label-inside' : 'label-outside'}`}85 style={{ width: `${widthPercent}%` }}86 >87 <span className="bar-graph-value">{displayLabel}</span>88 </div>89 </div>90 </div>91 );92 })}93 </div>94 </>95 );96}