You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义Grid布局下ApexRadialBarChart组件适配异常求助

问题:自定义Grid与ApexRadialBarChart适配异常

我使用了自定义Grid结构,该结构在不同屏幕尺寸下表现不符合预期,且外部定义的ApexRadialBarChart组件无法适配不同Grid结构。当组件尺寸缩小时,图表布局会变形。

index.jsx代码

<Grid container spacing={3} size={{ xs: 12, sm: 6, lg: 1.5 }}>
  <Grid size={{ xs: 12}}>
    {loading && <p>Yükleniyor...</p>}
    {!loading && data && (
      <ApexRadialBarChart
        series={dummyData.mini1.series} // Eksik seriyi eklemeyi unutmayın
        title={dummyData.mini1.title}   // Eksik başlığı eklemeyi unutmayın
      />
    )}
  </Grid>
  <Grid size={{ xs: 12}}>
    {loading && <p>Yükleniyor...</p>}
    {!loading && data && (
      <ApexRadialBarChart
        series={dummyData.mini2.series}
        title={dummyData.mini2.title}
      />
    )}
  </Grid>
</Grid>

自定义ApexRadialBarChart组件代码

'use client'

// Next Imports
import dynamic from 'next/dynamic'

// MUI Imports
import Card from '@mui/material/Card'
import { useTheme } from '@mui/material/styles'
import CardHeader from '@mui/material/CardHeader'
import CardContent from '@mui/material/CardContent'
import Typography from '@mui/material/Typography'

// Styled Component Imports
const AppReactApexCharts = dynamic(() => import('@/libs/styles/AppReactApexCharts'))

// Vars
const radialBarColors = {
  series1: '#fdd835',
  series2: '#32baff',
  series3: '#00d4bd',
  series4: '#7367f0',
  series5: '#FFA1A1'
}

// BİLEŞEN PROP'LARI DESTRUCTURING İLE ALACAK ŞEKİLDE DÜZENLENDİ
const ApexRadialBarChart = ({ 
  series, 
  title, 
  chartHeight = 400 // Varsayılan değer 400 olarak ayarlandı
}) => {
  // Hooks
  const theme = useTheme()

  // Vars
  const textSecondary = 'var(--mui-palette-text-secondary)'

  // Eğer series prop'u dışarıdan gelmezse, ApexCharts hata verebilir.
  // Bu nedenle boş bir dizi varsayılabilir.
  const chartSeries = series  
  const chartTitle = title

  const options = {
    stroke: { lineCap: 'round' },
    labels: ['Comments', 'Replies'],
    legend: {
      show: true,
      fontSize: '13px',
      position: 'bottom',
      labels: {
        colors: textSecondary
      },
      markers: {
        offsetX: theme.direction === 'rtl' ? 7 : -4
      },
      itemMargin: {
        horizontal: 9
      }
    },
    colors: [radialBarColors.series1, radialBarColors.series2, radialBarColors.series4],
    plotOptions: {
      radialBar: {
        hollow: { size: '30%' },
        track: {
          margin: 15,
          background: 'var(--mui-palette-customColors-trackBg)'
        },
        dataLabels: {
          name: {
            fontSize: '2rem'
          },
          value: {
            fontSize: '15px',
            fontWeight: 500,
            color: textSecondary
          },
          total: {
            show: false,
            fontWeight: 500,
            label: '',
            fontSize: '1.125rem',
            color: 'var(--mui-palette-text-primary)',
          }
        }
      }
    },
    grid: {
      padding: {
        top: -25,
        bottom: -30
      }
    }
  }

  return (
    <Card>
      {/* BAŞLIK PROP'TAN ALINACAK ŞEKİLDE DÜZENLENDİ */}
      <CardHeader 
        title={
          <Typography
            noWrap 
            variant="h5" 
            sx={{
              // display: 'block' doğru ama tek başına yetmiyor
              display: 'block', 
              overflow: 'hidden',
              textOverflow: 'ellipsis'
            }}
          >
            {chartTitle}
          </Typography>
        }
        // 💥 KRİTİK ÇÖZÜM: BAŞLIK ALANININ GENİŞLİĞİNİ ZORLAMA
        sx={{
          '& .MuiCardHeader-content': { 
            minWidth: 0, // Flexbox için kritik
            flex: '1 1 auto' // Mümkün olan en büyük alanı kapla
          }
        }}
      />
      <CardContent>
        <AppReactApexCharts 
          type='radialBar' 
          width='100%' 
          // YÜKSEKLİK PROP'TAN ALINACAK ŞEKİLDE DÜZENLENDİ
          height={chartHeight} 
          options={options} 
          // SERİLER PROP'TAN ALINACAK ŞEKİLDE DÜZENLENDİ
          series={chartSeries} 
        />
      </CardContent>
    </Card>
  )
}

export default ApexRadialBarChart

修复方案

1. Grid配置修正

MUI Grid组件需遵循官方规范:必须添加item属性,列数为1-12的整数(原lg:1.5为无效值)。修改后的Grid代码:

<Grid container spacing={3}>
  <Grid item xs={12} sm={6} lg={2}>
    {loading && <p>Yükleniyor...</p>}
    {!loading && data && (
      <ApexRadialBarChart
        series={dummyData.mini1.series}
        title={dummyData.mini1.title}
        chartHeight={300}
      />
    )}
  </Grid>
  <Grid item xs={12} sm={6} lg={2}>
    {loading && <p>Yükleniyor...</p>}
    {!loading && data && (
      <ApexRadialBarChart
        series={dummyData.mini2.series}
        title={dummyData.mini2.title}
        chartHeight={300}
      />
    )}
  </Grid>
</Grid>

2. 图表组件响应式优化

添加媒体查询钩子,动态调整图表元素尺寸,适配不同屏幕:

'use client'

import dynamic from 'next/dynamic'
import Card from '@mui/material/Card'
import { useTheme } from '@mui/material/styles'
import CardHeader from '@mui/material/CardHeader'
import CardContent from '@mui/material/CardContent'
import Typography from '@mui/material/Typography'
import useMediaQuery from '@mui/material/useMediaQuery'

const AppReactApexCharts = dynamic(() => import('@/libs/styles/AppReactApexCharts'))

const radialBarColors = {
  series1: '#fdd835',
  series2: '#32baff',
  series3: '#00d4bd',
  series4: '#7367f0',
  series5: '#FFA1A1'
}

const ApexRadialBarChart = ({ 
  series, 
  title, 
  chartHeight 
}) => {
  const theme = useTheme()
  const isSmallScreen = useMediaQuery(theme.breakpoints.down('sm'))
  const isMediumScreen = useMediaQuery(theme.breakpoints.between('sm', 'lg'))
  
  const finalHeight = chartHeight ?? (isSmallScreen ? 250 : isMediumScreen ? 300 : 400)
  const textSecondary = 'var(--mui-palette-text-secondary)'
  const chartSeries = series || []
  const chartTitle = title || ''

  const options = {
    stroke: { lineCap: 'round' },
    labels: ['Comments', 'Replies'],
    legend: {
      show: true,
      fontSize: isSmallScreen ? '11px' : '13px',
      position: 'bottom',
      labels: {
        colors: textSecondary
      },
      markers: {
        offsetX: theme.direction === 'rtl' ? 7 : -4
      },
      itemMargin: {
        horizontal: isSmallScreen ? 5 : 9
      }
    },
    colors: [radialBarColors.series1, radialBarColors.series2, radialBarColors.series4],
    plotOptions: {
      radialBar: {
        hollow: { size: '30%' },
        track: {
          margin: isSmallScreen ? 8 : 15,
          background: 'var(--mui-palette-customColors-trackBg)'
        },
        dataLabels: {
          name: {
            fontSize: isSmallScreen ? '1.2rem' : '2rem'
          },
          value: {
            fontSize: isSmallScreen ? '12px' : '15px',
            fontWeight: 500,
            color: textSecondary
          },
          total: {
            show: false,
            fontWeight: 500,
            label: '',
            fontSize: '1.125rem',
            color: 'var(--mui-palette-text-primary)',
          }
        }
      }
    },
    grid: {
      padding: {
        top: -25,
        bottom: -30
      }
    },
    responsive: [
      {
        breakpoint: 600,
        options: {
          plotOptions: {
            radialBar: {
              hollow: { size: '25%' }
            }
          }
        }
      }
    ]
  }

  return (
    <Card>
      <CardHeader 
        title={
          <Typography
            noWrap 
            variant={isSmallScreen ? "h6" : "h5"}
            sx={{
              display: 'block', 
              overflow: 'hidden',
              textOverflow: 'ellipsis'
            }}
          >
            {chartTitle}
          </Typography>
        }
        sx={{
          '& .MuiCardHeader-content': { 
            minWidth: 0,
            flex: '1 1 auto'
          }
        }}
      />
      <CardContent sx={{ padding: isSmallScreen ? '1rem' : undefined }}>
        <AppReactApexCharts 
          type='radialBar' 
          width='100%' 
          height={finalHeight} 
          options={options} 
          series={chartSeries} 
        />
      </CardContent>
    </Card>
  )
}

export default ApexRadialBarChart

3. 关键修复点

  • Grid组件必须添加item属性,列数设置为1-12的有效整数
  • 使用useMediaQuery动态调整图表字体、间距、高度,适配不同屏幕
  • 给series设置空数组默认值,避免无数据时报错
  • 新增ApexCharts的responsive配置,针对小屏优化图表结构

内容的提问来源于stack exchange,提问作者Numan Suzer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 07:14:54