DataScope26/WEB
0
1import * as React from 'react';2import Stack from '@mui/material/Stack';3import { PieChart } from '@mui/x-charts/PieChart';4import InfoIcon from './InfoIcon.jsx';5import "./PieChartGraph.css"6import ButtonPrimary from './ButtonPrimary.jsx';7 8// ──────────────────────────────────────────────────────────────9// Cuántos items se muestran en la LEYENDA antes del botón "Mostrar más...".10// Subí este número para mostrar más items de entrada.11// Nota: el gráfico de torta (las porciones) siempre muestra el 100% de12// las plataformas, recortar eso daría porcentajes incorrectos. Solo se13// recorta la lista de texto de abajo.14// ──────────────────────────────────────────────────────────────15const LEGEND_PREVIEW_COUNT = 1;16function CustomNoDataOverlay() {17 return (18 <div className="custom-no-data-overlay">19 No hay datos para mostrar20 </div>21 );22}23export default function PieChartGraph({ objectList, label, percentage, infoDescription, infoTitle, title }) {24 25 const [showAllLegend, setShowAllLegend] = React.useState(false);26 27 const initialIdInDataList = 'A'28 const dataList = objectList.map((item, index) => { return { value: item[percentage], label: item[label] , id: String.fromCharCode(initialIdInDataList.charCodeAt(0) + index) } })29 const pieChartProps = {30 series: [31 {32 id: 'sync',33 data: dataList,34 highlightScope: { highlight: 'item', fade: 'global' },35 valueFormatter: (item) => `${item.value}%`,36 },37 ],38 height: 200,39 width: 200,40 };41 42 const [highlightedItem, setHighlightedItem] = React.useState(null);43 44 const series = pieChartProps.series[0];45 const colors = series.data.map((_, i) => getColorForIndex(i));46 const fillStyles = colors.reduce((acc, color, i) => {47 acc[`& path:nth-of-type(${i + 1})`] = { fill: color };48 return acc;49 }, {});50 51 const legendItemsToShow = showAllLegend ? series.data : series.data.slice(0, LEGEND_PREVIEW_COUNT);52 const canExpandLegend = series.data.length > LEGEND_PREVIEW_COUNT;53 54 return (55 <Stack style={{ width: '100%', overflow: 'visible' }}>56 <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: '12px', marginBottom: '12px' }}>57 <span className="bar-graph-title">{title}</span>58 <InfoIcon 59 title={infoTitle}60 description={infoDescription}61 />62 </div>63 <div className="pie-chart-row">64 <div className="pie-legend">65 {legendItemsToShow.map((d, idx) => {66 const isHighlighted = highlightedItem && highlightedItem.dataIndex === idx && highlightedItem.seriesId === series.id;67 return (68 <div69 key={d.id || idx}70 className={`pie-legend-item ${isHighlighted ? 'highlighted' : ''}`}71 onMouseEnter={() => setHighlightedItem({ seriesId: series.id, dataIndex: idx })}72 onMouseLeave={() => setHighlightedItem(null)}73 >74 <span className="pie-legend-swatch" style={{ background: getColorForIndex(idx) }} />75 <span className="pie-legend-label">{d.label}</span>76 <span className="pie-legend-value">{d.value}%</span>77 </div>78 )79 })}80 {canExpandLegend && (81 <ButtonPrimary82 type="button"83 className="btn-Piechart-toggle"84 onClick={() => setShowAllLegend(!showAllLegend)}85 >86 {showAllLegend ? "Ver menos" : "Ver más..."}87 </ButtonPrimary>88 )}89 </div>90<PieChart91 {...pieChartProps}92 93 hideLegend={true}94 95 highlightedItem={highlightedItem}96 97 onHighlightChange={(item) =>98 setHighlightedItem(99 item100 ? {101 seriesId: item.seriesId,102 dataIndex: item.dataIndex103 }104 : null,105 )106 }107 108 slots={{109 noDataOverlay: CustomNoDataOverlay,110 }}111 112 sx={{113 '& path': {114 stroke: 'var(--bg)',115 },116 ...fillStyles,117 }}118/> </div>119 </Stack>120 )121}122 123function getColorForIndex(i) {124 const palette = ['rgb(66, 84, 251)', 'rgb(255, 180, 34)', 'rgb(250, 79, 88)', 'rgb(13, 190, 255)', 'rgb(34, 191, 117)'];125 return palette[i % palette.length];126}