CoolFace
Apppublic

DataScope26/WEB

sourceHugging Faceupdated 7d agoView on Hugging Face
0likes
PieChartGraph.jsx126 linesDownload Raw Back to components
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}